
Vider la mémoire d'un PPL avec un exploit userland.
⚠️ 2022-07-24 - Depuis Windows 10 21H2 10.0.19044.1826 (mise à jour de juillet 2022), l'exploit implémenté dans PPLdump ne fonctionne plus. Un correctif dans NTDLL empêche désormais les PPL de charger des Known DLLs. Plus d'informations ici.
Cet outil implémente un exploit userland qui a été initialement discuté par James Forshaw (alias @tiraniddo) - dans cet article de blog - pour vider la mémoire de n'importe quel PPL en tant qu'administrateur.
J'ai écrit deux articles de blog à propos de cet outil. La première partie concerne les concepts des Processus Protégés tandis que la seconde aborde la technique de contournement elle-même.
Il suffit d'exécuter l'exécutable sans aucun argument pour obtenir une aide détaillée.
c:\Temp>PPLdump64.exe
_____ _____ __ _
| _ | _ | | _| |_ _ _____ ___
| __| __| |__| . | | | | . | version 0.4
|__| |__| |_____|___|___|_|_|_| _| by @itm4n
|_|
Description:
Dump the memory of a Protected Process Light (PPL) with a *userland* exploit
Usage:
PPLdump.exe [-v] [-d] [-f] <PROC_NAME|PROC_ID> <DUMP_FILE>
Arguments:
PROC_NAME The name of a Process to dump
PROC_ID The ID of a Process to dump
DUMP_FILE The path of the output dump file
Options:
-v (Verbose) Enable verbose mode
-d (Debug) Enable debug mode (implies verbose)
-f (Force) Bypass DefineDosDevice error check
Examples:
PPLdump.exe lsass.exe lsass.dmp
PPLdump.exe -v 720 out.dmp
Tout d'abord, les PPL ont été introduites avec Windows 8.1, donc les versions plus anciennes de Windows ne sont évidemment pas prises en charge. Ce projet cible principalement Windows 10 (et ses éditions serveur) mais je l'ai aussi testé sur des versions plus anciennes. Vous trouverez un tableau récapitulatif des tests que j'ai effectués dans la section éponyme.
Les autres outils de contournement PPL exécutent généralement du code arbitraire dans le noyau via un pilote signé numériquement. Celui-ci est différent car il n'implique que des astuces en espace utilisateur et est (presque) sans fichier.
Cet outil exploite une astuce très ingénieuse initialement discutée par James Forshaw en 2018 (voir Crédits). Elle implique l'utilisation de la fonction API DefineDosDevice pour tromper le système et créer une entrée arbitraire Known DLL. Étant donné que les PPL ne vérifient pas la signature numérique des Known DLL, cela peut ensuite être utilisé pour effectuer une attaque de détournement de DLL et exécuter du code arbitraire à l'intérieur d'un PPL.
Bien que cet outil effectue une attaque de détournement de DLL en deuxième étape, il ne crée pas de nouveau fichier DLL sur le disque. Au lieu de cela, il utilise une transaction NTFS pour remplacer virtuellement le contenu d'une DLL existante, une technique directement inspirée du travail de @_ForrestOrr (voir Crédits).
La réponse courte est « non ». Premièrement, il n'implique aucun accès direct au noyau, donc il n'y a aucun risque de provoquer un écran bleu de la mort de ce point de vue. Dans le pire des cas, l'outil pourrait échouer à supprimer l'entrée Known DLL créée, mais cela ne provoquera pas un déni de service. Elle restera simplement là jusqu'au prochain redémarrage de la machine. Comme l'entrée créée serait simplement un lien symbolique pointant vers une section inexistante, le système finira par revenir à l'emplacement par défaut (c'est-à-dire le dossier System32), donc cela n'impactera pas les autres programmes en cours d'exécution sur la machine.
⚠️ L'exploit échoue sur les machines Windows 8.1 / Server 2012 R2 entièrement mises à jour. Je n'ai pas encore déterminé quel correctif a provoqué l'erreur.
[-] DefineDosDevice failed with error code 6 - The handle is invalid.
⚠️ Sous Windows 8.1 / Server 2012 R2, vous pourriez également devoir compiler le binaire de manière statique (voir « Instructions de compilation » ci-dessous).
Cette solution Visual Studio comprend deux projets (l'exécutable et une DLL de charge utile) qui doivent être compilés dans un ordre spécifique. Tout est préconfiguré, il vous suffit donc de suivre ces instructions simples. La DLL de charge utile compilée est automatiquement intégrée dans l'exécutable final.
Release / x64 ou Release / x86 selon l'architecture de la machine cible.Build > Build Solution.Sous Windows 8.1 / Server 2012 R2, vous pourriez devoir compiler le binaire de manière statique.
PPLdump.Configuration Properties > C/C++ > Code Generation.Multi-threaded (/MT) comme option Runtime Library.| Version Windows | Build | Édition | Arch | Admin | SYSTEM |
|---|
| Windows 10 20H2 | 19042 | Pro | x64 | ✔️ | ✔️ |
| Windows 10 20H2 | 19042 | Pro | x86 | ✔️ | ✔️ |
| Windows 10 1909 | 18363 | Pro | x64 | ✔️ | ✔️ |
| Windows 10 1507 | 10240 | Educational | x64 | ✔️ | ✔️ |
| Windows 10 1507 | 10240 | Home | x64 | ✔️ | ✔️ |
| Windows 10 1507 | 10240 | Pro | x64 | ✔️ | ✔️ |
| Windows Server 2019 | 17763 | Standard | x64 | ✔️ | ✔️ |
| Windows Server 2019 | 17763 | Essentials | x64 | ✔️ | ✔️ |
| Windows 8.1 | 9600 | Pro | x64 | ⚠️ | ⚠️ |
| Windows Server 2012 R2 | 9600 | Standard | x64 | ⚠️ | ⚠️ |