
Winstrument is a framework of modular scripts to aid in instrumenting Windows software using Frida for reverse engineering and attack surface analysis.
Winstrument est un framework de scripts modulaires visant à faciliter l'instrumentation de logiciels Windows à l'aide de Frida pour la rétro-ingénierie et l'analyse de la surface d'attaque.
Ce projet prend en charge Python 3.7. En supposant que vous ayez déjà Python et pip installés, exécutez simplement :
pip install winstrument
puis pour exécuter le programme, lancez :
winstrument
Notez que l'outil est actuellement expérimental et peut parfois se figer ou rencontrer d'autres problèmes de stabilité.
Dans certains cas, comme sur une installation fraîche de Windows 10, vous pouvez rencontrer une erreur SSL dans pip lors de l'installation de Frida. Si cela se produit, consultez Dépannage ci-dessous.
Pour lancer le REPL Winstrument, exécutez simplement winstrument.
Voici un exemple rapide d'instrumentation de notepad.exe avec le module registry. Pour des informations complètes sur les commandes CLI disponibles, voir la section CLI ci-dessous.
PS C:\winstrument> winstrument
> set target C:\Windows\System32\notepad.exe
> use registry
> run
Spawned 1144
instrumented process with pid: 1144 and path: C:\Windows\System32\notepad.exe
<User closes notepad from GUI>
detached from 1144 for reason process-terminated
> show registry
module time target function hkey subkey value
-------- ----------------- ------------------------------- ---------------- ------------------ --------------------------------------------------------------------------- ---------------------------------
registry 2019-08-19 07:03:07 C:\Windows\System32\notepad.exe RegGetValueW 0x2f4 SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize AppsUseLightTheme
<...>
Dans l'exemple ci-dessus, l'utilisateur indique le processus cible, en l'occurrence notepad.exe. Il indique ensuite qu'il souhaite utiliser le module registry, qui énumère les appels système liés au registre effectués par le programme. Une fois le processus terminé (l'utilisateur ferme le Bloc-notes), la sortie stockée peut être consultée à l'aide de show registry.
Le fichier principal python winstrument.py initialise le périphérique Frida et génère une instance du processus cible.
cmdline.py fournit une interface en ligne de commande utilisant cmd2. C'est le point d'entrée principal du script lorsque Winstrument est exécuté directement depuis la ligne de commande. Les commandes sont documentées ci-dessous.
Il parcourt ensuite chaque module activé, l'instancie et appelle la méthode load_scripts() de ce module pour instrumenter le processus.
Enfin, il appelle get_output() et on_finish() pour chaque module lorsqu'il se détache de la cible.
Les modules sont contenus dans des fichiers .py dans le répertoire modules/. Un module consiste en une sous-classe de base_module.BaseInstrumentation qui définit le code à injecter, la gestion des messages pour ce code injecté et la sortie.
Les API des modules sont définies plus en détail dans la section « Modules » ci-dessous.
Chaque module stocke des métadonnées telles que sa description dans modules/metadata.toml. La section doit être précédée du nom du module (insensible à la casse).
Par exemple, voici la section correspondant au module dlls :
[DLLS]
description = """Hooks LoadLibrary-family system calls and outputs DLL loads where part of the search path might be
writable by the current user or a low-privileged user group."""
Le programme stocke les paramètres dans settings.toml dans %APPDATA%/winstrument.
Comme la plupart des modules, sinon tous, injectent du Javascript dans le processus cible, le répertoire modules/js/ contient des extraits de code Javascript Frida qui sont chargés et injectés par les modules.
Ces fichiers doivent porter le même nom que le module, c'est-à-dire que le module dlls.py utiliserait le JS de js/dlls.js.
Comme décrit ci-dessus, chaque module hérite de BaseInstrumentation depuis base_module.py
Chaque module doit définir son nom (le nom des fichiers python et js sans l'extension) comme attribut statique de classe appelé modulename.
Les modules peuvent utiliser ou surcharger les méthodes suivantes de BaseInstrumentation :
__init__(self,*args,**kwargs) - En plus du code d'initialisation spécifique au module, ce constructeur doit appeler super().__init__(*args,**kwargs).load_script(self) - Cette méthode ne devrait généralement pas avoir besoin d'être surchargée, car l'implémentation dans BaseInstrumentation devrait être suffisante pour la plupart des cas d'utilisation. Pour s'accrocher aux événements Frida, surchargez plutôt register_callbacks(). load_script doit être utilisé pour charger le fichier javascript à instrumenter, appeler session.create_script de Frida, ajouter les callbacks souhaités, puis appeler la méthode load() de l'objet script pour instrumenter.register_callbacks(self) - Appelé par BaseInstrumentation.load_script avant de charger le script dans le processus cible. Utilisé pour enregistrer des événements tels que _session.on('message'), etc. La version de ajoute un hook pour on_message par défaut.Le shell Winstrument fournit les commandes suivantes :
list - Affiche tous les modules disponibles et chargésload <modulename> / use <modulename> - Active le module portant le nom donnéunload <modulename> - Désactive le module portant le nom donnéset [setting [value]] - Sans argument, affiche tous les paramètres et leurs valeurs. Avec un argument, affiche la valeur de setting. Avec deux arguments, définit setting à value. Les paramètres persistent entre les exécutions.show [modulename [format]] - Affiche la sortie stockée de modulename dans le format spécifié. Exécutez sans arguments pour voir une liste des formateurs.info <modulename> - Affiche une description du module portant le nom donné.Cela semble se produire principalement sur une nouvelle installation de Windows. Le setup.py de Frida essaie de télécharger un fichier .egg depuis https://files.pythonhosted.org. Dans certains cas, cela échoue car le certificat SSL pour ce domaine ne se vérifie pas. Cela semble être un effet secondaire de la façon dont Windows charge les autorités de certification racines. Windows ne semble pas inclure toutes les autorités de certification racines dans une installation par défaut, préférant plutôt les télécharger au besoin lorsque des sites Web sont visités. Par conséquent, l'autorité de certification racine qui a signé le certificat SSL de files.pythonhosted.org pourrait ne pas être dans le magasin de confiance du système.
Pour résoudre ce problème, visitez https://files.pythonhosted.org manuellement dans Edge ou Chrome pour amener Windows à ajouter l'autorité de certification racine à son magasin de confiance, puis réessayez pip install.
Notez que visiter la page dans Firefox ne fonctionnera pas, car Firefox utilise son propre magasin de confiance plutôt que celui du système.
Winstrument est sous licence GPLv3. Pour plus de détails, consultez le fichier LICENSE.
BaseInstrumentationwrite_message(message) - Prend un message de type JSON comme un dict, l'écrit dans la base de données sqlite et le sauvegarde pour une sortie ultérieure.post_load(self) - Appelé par BaseInstrumentation.load_script après le chargement du script dans le processus cible. Cela pourrait être utilisé, par exemple, pour appeler des méthodes rpc exportées par le script.get_output(self) - Appelé par le script principal lorsque la cible est détachée. Cette méthode doit retourner une liste, où chaque entrée est un objet MoudleMessage (de data/module_message.py). En général, il n'est pas nécessaire de la surcharger.on_message(self,message,data) - Callback pour gérer l'événement message de Frida, déclenché par send dans le JS injecté.on_finish(self) - Callback appelé par le script principal lorsque la cible se détache. Effectuez ici toutes les opérations de nettoyage nécessaires.runq / quit / exit - Quitte le CLI (évidemment).