
Winstrument is a framework of modular scripts to aid in instrumenting Windows software using Frida for reverse engineering and attack surface analysis.
Winstrument es un framework de scripts modulares para ayudar a instrumentar software de Windows usando Frida para ingeniería inversa y análisis de superficie de ataque.
Este proyecto soporta Python 3.7. Asumiendo que ya tienes Python y pip instalados, simplemente:
pip install winstrument
y luego para ejecutar el programa, ejecuta:
winstrument
Ten en cuenta que la herramienta actualmente es experimental, y puede a veces congelarse o tener otros problemas de estabilidad.
En algunos casos, como una instalación limpia de Windows 10, puedes encontrarte con un error SSL en pip al instalar Frida. Si esto ocurre, consulta Solución de problemas más abajo.
Para ejecutar el REPL de winstrument, simplemente ejecuta winstrument.
Aquí tienes un ejemplo rápido de instrumentación de notepad.exe con el módulo registry. Para información completa sobre los comandos CLI disponibles, consulta la sección CLI más abajo.
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
<...>
En el ejemplo anterior, el usuario indica el proceso objetivo, en este caso notepad.exe. Luego indica que quiere usar el módulo registry, que enumera las llamadas al sistema relacionadas con el registro realizadas por el programa. Cuando el proceso finaliza (el usuario cierra Notepad), la salida almacenada se puede ver usando show registry.
El archivo principal de Python winstrument.py inicializa el dispositivo Frida y lanza una instancia del proceso objetivo.
cmdline.py proporciona una interfaz de línea de comandos usando cmd2. Este es el principal punto de entrada del script cuando Winstrument se ejecuta directamente desde la línea de comandos. Los comandos están documentados más abajo.
Luego itera a través de cada módulo habilitado, lo instancia y llama al método load_scripts() de ese módulo para instrumentar el proceso.
Finalmente, llama a get_output() y on_finish() para cada módulo cuando se desvincula del objetivo.
Los módulos están contenidos en archivos .py en el directorio modules/. Un módulo consiste en una subclase de base_module.BaseInstrumentation que define el código a inyectar, el manejo de mensajes para ese código inyectado y la salida.
Las APIs de los módulos se definen más adelante en la sección "Módulos" más abajo.
Cada módulo almacena metadatos como su descripción en modules/metadata.toml. La sección debe tener como encabezado el nombre del módulo (sin distinguir mayúsculas de minúsculas).
Por ejemplo, aquí está la sección correspondiente al módulo 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."""
El programa almacena la configuración en settings.toml en %APPDATA%/winstrument.
Como la mayoría, si no todos, los módulos inyectarán Javascript en el proceso objetivo, el directorio modules/js/ contiene fragmentos de Javascript de Frida que son cargados e inyectados por los módulos.
Estos archivos deben tener el mismo nombre que el módulo, es decir, el módulo dlls.py usaría JS de js/dlls.js.
Como se describió anteriormente, cada módulo subclasifica BaseInstrumentation de base_module.py.
Cada módulo debe definir su nombre (el nombre de los archivos python y js sin la extensión) como un atributo de clase estático llamado modulename.
Los módulos pueden usar o sobrescribir los siguientes métodos de BaseInstrumentation:
__init__(self,*args,**kwargs) - Además de cualquier código de inicialización específico del módulo, este constructor debe llamar a super().__init__(*args,**kwargs).load_script(self) - Este método generalmente no debería necesitar ser sobrescrito, ya que la implementación en BaseInstrumentation debería ser suficiente para la mayoría de los casos de uso. Para enganchar eventos de Frida, sobrescribe register_callbacks() en su lugar. load_script debería usarse para cargar el archivo javascript a instrumentar, llamar a session.create_script de Frida, añadir los callbacks deseados y luego llamar al método load() del objeto script para instrumentar.register_callbacks(self) - Llamado por BaseInstrumentation.load_script antes de cargar el script en el proceso objetivo. Se usa para registrar eventos como _session.on('message'), etc. La versión de añade un hook para on_message por defecto.El shell de Winstrument proporciona los siguientes comandos:
list - Muestra todos los módulos disponibles y cargados.load <modulename>/use <modulename> - Habilita el módulo con el nombre dado.unload <modulename> - Deshabilita el módulo con el nombre dado.set [setting [value]] - Sin argumentos, muestra todos los ajustes y sus valores. Con un argumento, muestra el valor de setting. Con dos argumentos, establece setting a value. Los ajustes persisten entre múltiples ejecuciones.show [modulename [format]] - Muestra la entrada almacenada de modulename en el format especificado. Ejecútalo sin argumentos para ver una lista de formateadores.info <modulename> - Imprime una descripción del módulo con el nombre dado.Esto parece ocurrir sobre todo en una instalación nueva de Windows. El setup.py de Frida intenta descargar un archivo .egg desde https://files.pythonhosted.org. En algunos casos, esto falla porque el certificado SSL de ese dominio no se verifica. Esto parece ser un efecto secundario de la forma en que Windows carga las CA raíz. Windows parece no incluir todas las CA raíz en una instalación predeterminada, prefiriendo en su lugar descargarlas según sea necesario cuando se visitan sitios web. Como resultado, la CA raíz que firmó el certificado SSL de files.pythonhosted.org podría no estar en el almacén de confianza del sistema.
Para resolver este problema, visita https://files.pythonhosted.org manualmente en Edge o Chrome para que Windows añada la CA raíz a su almacén de confianza, y luego intenta pip install de nuevo.
Ten en cuenta que visitar la página en Firefox no funcionará, porque Firefox usa su propio almacén de confianza en lugar del almacén del sistema.
Winstrument está licenciado bajo GPLv3. Para más detalles, consulta el archivo LICENSE.
BaseInstrumentationwrite_message(message) toma un mensaje tipo JSON como un dict, lo escribe en la base de datos sqlite y lo guarda para ser emitido más tarde.post_load(self) Llamado por BaseInstrumentation.load_script después de que el script se cargue dentro del proceso objetivo. Esto podría usarse, por ejemplo, para llamar a métodos rpc exportados por el script.get_output(self) - Llamado por el script principal cuando el objetivo se desvincula. Este método debería devolver una lista, donde cada entrada es un objeto MoudleMessage (de data/module_message.py). Generalmente no necesita ser sobrescrito.on_message(self,message,data) - Callback para manejar el evento message de frida, que se dispara con send en el JS inyectado.on_finish(self) - Callback llamado por el script principal cuando el objetivo se desvincula. Realiza aquí cualquier operación de limpieza necesaria.run - Inicia la instrumentación.q/quit/exit - Sale de la CLI (obviamente).