SCCM RecentlyUsedApps : preuves d'exécution dans WMI
Lire CCM_RecentlyUsedApps dans le dépôt WMI : quels programmes chaque utilisateur a lancés, quand et combien de fois, y compris les anciennes copies d'OBJECTS.DATA.
En bref. Sur les machines équipées du client Configuration Manager (SCCM / ConfigMgr), le dépôt WMI contient CCM_RecentlyUsedApps : un enregistrement par exécutable et par utilisateur, avec le chemin complet, les informations de version du fichier, le dernier utilisateur, LastUsedTime et un LaunchCount. C'est une preuve d'exécution qui survit à la suppression du binaire, elle se trouve dans le même OBJECTS.DATA que celui que vous collectez déjà pour la persistance WMI, et les anciennes copies de chaque enregistrement peuvent être récupérées dans l'espace libéré.
D'où viennent ces données
Le composant de contrôle logiciel (software metering) du client ConfigMgr observe les démarrages de programmes et en conserve un résumé dans WMI, dans l'espace de noms root\ccm\SoftwareMeteringAgent, classe CCM_RecentlyUsedApps. Configuration Manager s'en sert pour ses rapports d'utilisation des logiciels ; pour un enquêteur, c'est un relevé par utilisateur de ce qui s'est exécuté. Pas de client ConfigMgr, pas de données — vérifiez donc d'abord :
Get-Service CcmExec -ErrorAction SilentlyContinue
Get-CimInstance -Namespace root/ccm/SoftwareMeteringAgent -ClassName CCM_RecentlyUsedApps |
Sort-Object LastUsedTime -Descending |
Select-Object LastUsedTime, LastUserName, FolderPath, ExplorerFileName, LaunchCount, CompanyName
Cette requête ne montre que les enregistrements actifs, en passant par WMI lui-même. Pour l'investigation, collectez tout le dossier Repository : rien de plus n'est nécessaire pour SCCM, la classe se trouve dans les mêmes fichiers.
Les champs utiles
| Propriété | Ce qu'elle indique |
|---|---|
FolderPath, ExplorerFileName | D'où l'exécutable a été lancé, et son nom sur le disque |
LastUserName | Le compte qui l'a lancé (un enregistrement par utilisateur) |
LastUsedTime | Le lancement le plus récent de ce fichier par cet utilisateur |
LaunchCount | Les lancements comptés par le client |
CompanyName, ProductName, FileDescription, FileVersion, ProductVersion, OriginalFileName | Les informations de version du fichier |
FileSize, FilePropertiesHash, SoftwarePropertiesHash | La taille et les empreintes propres au client des propriétés du fichier et du produit |
msiDisplayName, msiPublisher, msiVersion, ProductCode | Le produit MSI installé auquel appartient le fichier, s'il y en a un |
OriginalFileName et les champs de version viennent du fichier lui-même : un outil renommé y garde son nom d'origine, et un outil sans aucune information de version se remarque à côté des logiciels signés des éditeurs.
Bien lire LastUsedTime
LastUsedTime est une chaîne CIM DATETIME : aaaammjjHHMMSS.mmmmmm, puis un signe et trois chiffres de décalage par rapport à l'UTC, en minutes. 20260914100914.000000+000 vaut 10:09:14 UTC. Une valeur se terminant par +120 serait écrite deux heures en avance sur l'UTC : son heure UTC est donc deux heures plus tôt. Convertissez avec le décalage présent dans la valeur plutôt que de supposer un fuseau, et gardez la chaîne brute dans vos notes.
Deux limites à garder en tête :
- C'est le dernier lancement par cet utilisateur, ni le premier ni chacun d'eux. Le premier lancement est en général mieux daté par le Prefetch ou l'Amcache.
LaunchCountest cumulatif depuis que le client suit le fichier. Un compte de 1 correspond à une seule exécution ; un compte de 2 avec unLastUsedTimerécent implique au moins une exécution antérieure.
Les anciennes copies dans OBJECTS.DATA
Chaque mise à jour réécrit l'enregistrement. Comme pour les abonnements WMI supprimés, la version précédente n'est pas effacée : elle reste dans une page non mappée ou dans l'espace résiduel d'une page jusqu'à ce que WMI réutilise l'espace. Le carving de l'en-tête d'enregistrement (l'empreinte du nom de la classe) récupère ces copies avec leur propre LastUsedTime et leur propre LaunchCount. Une copie libérée avec un compte de 1 et une heure antérieure, à côté d'une copie active avec un compte de 2, date aussi la première exécution.
La même approche est celle du CCM_RUA_Finder.py de David Pany (WMI_Forensics) ; python-cim lit les enregistrements actifs via l'index.
Ce qu'il faut chercher
- Dossiers modifiables par l'utilisateur :
C:\Users\Public\,AppData,Downloads,C:\ProgramData\,C:\Windows\Temp\. Les logiciels installés par un administrateur résident dansProgram FilesouWindows. - Aucune information de version (
CompanyNamevide) pour un exécutable hors des dossiers habituels. - LaunchCount = 1 pour un outil : la préparation, l'exfiltration ou le nettoyage ne sont souvent lancés qu'une fois.
- Entrées rares : le seul programme vu dans son dossier, ou vu sur une seule machine du parc.
- Chronologie : derniers lancements dans la fenêtre de l'incident, ou proches de la création d'un abonnement WMI sur le même hôte.
Aucun de ces signes n'est une preuve à lui seul. Identifiez le fichier (empreinte depuis le disque ou les sauvegardes, éditeur, installeur) avant de conclure.
Un exemple commenté
Le dépôt d'exemple de l'outil (hôte fictif FIN-WKS-07) contient m64.exe dans C:\ProgramData\Intel\, lancé par FIN\svc_backup à 10:09 UTC avec un compte de 2 et sans informations de version, et rclone.exe dans C:\Users\Public\, lancé une fois à 10:47. Une copie libérée de l'enregistrement de m64.exe montre un premier lancement à 10:02 avec un compte de 1. Dans les abonnements WMI du même dépôt, un consommateur dont l'heure d'en-tête d'enregistrement est 10:31 lance ce même m64.exe quelques minutes après chaque démarrage. Ouvrez l'outil, chargez l'exemple et passez à Preuves d'exécution (SCCM) pour suivre tout cela avec la plage horaire.