
Scripts de Ghidra para recuperar definiciones de cadenas en binarios de Go
Scripts para recuperar definiciones de cadenas en binarios de Go con análisis P-Code. Probado con x86, x86-64, ARM y ARM64.
Estos se pueden encontrar en la categoría Golang del Script Manager.
GoDynamicStrings.java
GoFuncCallStrings.java
GoStaticStrings.java
GoKnownStrings.java
data/known_strings.json.GoStringFiller.java
go.string.* después del análisis inicial, basándose en el orden ascendente de longitud de los datos de cadenas.También hay un par de variaciones especiales del script de análisis de cadenas dinámicas:
GoDynamicStringsSingle.java
GoDynamicStrings.java, pero utiliza un único proceso del descompilador. Úselo si analizar un binario hace que los procesos paralelos del descompilador agoten la memoria del sistema.GoDynamicStringsHigh.java
Esto se puede encontrar en la categoría PCode del Script Manager.
PrintHighPCode.java
A continuación se presenta el flujo general para usar estos scripts y recuperar definiciones de cadenas en un binario de Go:
.rodata, .rdata o __rodata. Luego haga clic derecho en el listado de código y elija "Clear Code Bytes".GoKnownStrings.java para detectar algunas cadenas estándar.GoStaticStrings.java.GoFuncCallStrings.java (si la versión del binario de Golang es compatible con las funciones integradas de Golang de Ghidra).GoDynamicStrings.java.GoStringFiller.java.
go.string.* en la primera cadena de un byte.En Ghidra:
Para Eclipse con el complemento GhidraDev:
Compilar con Eclipse:
Compilar directamente con Gradle:
$ cd Ghostrings
$ gradle -PGHIDRA_INSTALL_DIR=<ghidra_install_dir>
Un problema bien conocido al hacer ingeniería inversa de programas Go es que la falta de terminadores nulos en las cadenas de Go dificulta la recuperación de definiciones de cadenas a partir de binarios compilados. Muchos de los valores de cadena constantes de un programa Go se almacenan juntos en un bloque gigante en la compilación, sin caracteres terminadores incorporados en los datos de cadena para marcar dónde termina una cadena y comienza otra. Incluso un programa simple que solo imprime "Hello world!" contiene más de 1,500 cadenas relacionadas con el sistema de tiempo de ejecución de Go y otras bibliotecas estándar. Esto puede hacer que las implementaciones típicas de descubrimiento de cadenas ASCII, como la proporcionada por Ghidra, creen definiciones de cadenas falsas positivas de decenas de miles de caracteres de longitud.
En lugar de cadenas terminadas en nulo, Go utiliza una estructura de cadena que consiste en un puntero y un valor de longitud. Muchas de estas estructuras de cadena se crean en la pila del programa en tiempo de ejecución, por lo que recuperar las ubicaciones de inicio y los valores de longitud de cada cadena requiere analizar el código de máquina compilado. Existen algunos scripts que realizan este análisis comprobando ciertos patrones de instrucciones x86-64, pero omiten estructuras creadas con variaciones no manejadas de instrucciones que, en última instancia, tienen el mismo efecto en la pila, y además están restringidos a una ISA específica.
Ghostrings evita ambos problemas al trabajar con las operaciones P-Code simplificadas e independientes de la arquitectura producidas por el análisis del descompilador de Ghidra.
Copyright 2022 NCC Group. Publicado bajo la licencia GPLv3 (ver LICENSE).
Autor principal del proyecto: James Chambers [email protected]
go.string.* y defina las cadenas con puntos de inicio y fin obvios.
GoStringFiller.java, identifique dónde cambian las longitudes de las cadenas en los datos de cadenas no definidos y defina las cadenas más cercanas a ese límite. Luego vuelva a ejecutar GoStringFiller.java para rellenar automáticamente los lugares donde pueda determinar correctamente la longitud de las cadenas no definidas restantes.