Analisis Estatico Basico: Strings, Hashes y Metadatos
Fundamentos del analisis estatico de malware. Extraccion de strings con strings y FLOSS, hashes criptograficos y fuzzy hashing con ssdeep, metadatos con PEStudio y Detect It Easy. Primer triaje de muestras sospechosas.
El primer contacto con una muestra sospechosa
Antes de abrir un desensamblador o ejecutar un binario en sandbox, el analisis estatico basico responde preguntas fundamentales en minutos: que tipo de archivo es, para que plataforma fue compilado, que strings contiene, si esta empaquetado, y si alguien ya lo ha analizado.
Este primer triaje no requiere conocimientos avanzados de reverse engineering. Con un punado de herramientas gratuitas y un flujo de trabajo sistematico, cualquier analista SOC puede extraer indicadores utiles de una muestra sospechosa.
Paso 1: Identificacion del archivo
Nunca confiar en la extension del archivo. Un .pdf puede ser un .exe renombrado, y un .docx puede ser un archivo con macros maliciosas.
# Identificar el tipo real del archivo
file sample.suspicious
# sample.suspicious: PE32+ executable (GUI) x86-64, for MS Windows
# Verificar el magic number manualmente
xxd sample.suspicious | head -2
# 00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
El magic number "MZ" (0x4D5A) confirma que es un PE de Windows. Otros magic numbers comunes:
| Magic | Hex | Formato |
|---|---|---|
| MZ | 4D 5A | PE (Windows) |
| .ELF | 7F 45 4C 46 | ELF (Linux) |
| Mach-O 64 | CF FA ED FE | Mach-O (macOS, little-endian) |
| PK | 50 4B | ZIP (incluye .docx, .xlsx, .apk, .jar) |
| 25 50 44 46 | ||
| .doc | D0 CF 11 E0 | OLE (Office antiguo) |
Paso 2: Hashes criptograficos
Los hashes son la huella digital del binario. Permiten buscar si la muestra ya ha sido analizada por la comunidad.
# Generar hashes
md5sum sample.exe
sha1sum sample.exe
sha256sum sample.exe
# O con Python
python3 -c "
import hashlib
data = open('sample.exe', 'rb').read()
print('MD5: ', hashlib.md5(data).hexdigest())
print('SHA1: ', hashlib.sha1(data).hexdigest())
print('SHA256:', hashlib.sha256(data).hexdigest())
print('Tamano:', len(data), 'bytes')
"
Donde buscar los hashes:
| Servicio | URL | Que ofrece |
|---|---|---|
| VirusTotal | virustotal.com | Detecciones de 70+ AVs, relaciones |
| MalwareBazaar | bazaar.abuse.ch | Base de datos de muestras con tags |
| Hybrid Analysis | hybrid-analysis.com | Reportes de sandbox |
| ANY.RUN | any.run | Analisis interactivo en sandbox |
| Joe Sandbox | joesandbox.com | Analisis automatizado detallado |
Importante: SHA256 es el hash estandar para identificacion de malware. MD5 y SHA1 tienen colisiones conocidas y se usan como complemento, no como identificador principal.
Paso 3: Fuzzy Hashing con ssdeep
Los hashes criptograficos cambian completamente con cualquier modificacion del archivo. ssdeep genera hashes que permiten medir la similitud entre archivos:
# Generar hash ssdeep
ssdeep sample.exe
# 384:Gm4eLNqRaR2q/b2V0HoS7kBn:Gm4eLNq/qb2V0HoS7c, "sample.exe"
# Comparar dos archivos
ssdeep -d sample1.exe sample2.exe
# sample1.exe matches sample2.exe (87)
# Comparar contra base de datos
ssdeep -r /malware/samples/ > hashes.txt
ssdeep -m hashes.txt new_sample.exe
Un match de 80% o mas indica que los binarios son variantes de la misma familia. ssdeep es especialmente util para:
- Identificar variantes de malware que usan custom packers (cada empaquetado produce hash SHA256 diferente pero ssdeep similar).
- Agrupar muestras de la misma campana.
- Detectar actualizaciones incrementales de malware.
Import Hash (ImpHash)
El ImpHash es un hash MD5 de la lista de imports del PE (DLLs y funciones en orden). Binarios compilados con el mismo codigo fuente y linker producen el mismo ImpHash aunque el binario sea diferente:
import pefile
pe = pefile.PE("sample.exe")
print("ImpHash:", pe.get_imphash())
El ImpHash es un excelente indicador para agrupar muestras de la misma familia cuando el codigo fuente no ha cambiado.
Paso 4: Extraccion de strings
Los strings son la fuente de informacion mas accesible en un binario. URLs, IPs, rutas de archivos, mensajes, nombres de APIs y comandos pueden aparecer en texto claro.
strings (herramienta basica)
# Strings ASCII (minimo 6 caracteres)
strings -n 6 sample.exe
# Strings Unicode (UTF-16LE, comun en Windows)
strings -e l sample.exe
# Ambos, guardando en archivo
strings -a sample.exe > strings_ascii.txt
strings -e l sample.exe >> strings_unicode.txt
# Buscar patrones especificos
strings sample.exe | grep -iE "http|https|ftp|\.exe|\.dll|\.bat"
strings sample.exe | grep -iE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
strings sample.exe | grep -iE "HKEY|CurrentVersion|Run"
FLOSS (FLARE Obfuscated String Solver)
FLOSS de Mandiant va mas alla de strings: emula las funciones de descifrado del malware para extraer strings ofuscadas:
# Analisis completo
floss sample.exe
# Solo strings decodificadas (las interesantes)
floss sample.exe --no-static-strings
# Con longitud minima
floss sample.exe -n 8
# Output JSON para procesamiento
floss sample.exe -o json > floss_output.json
FLOSS clasifica los strings en tres categorias:
- Static strings: Visibles con strings normal.
- Decoded strings: Extraidas emulando funciones de descifrado.
- Stack strings: Construidas caracter a caracter en el stack.
Que buscar en los strings
| Categoria | Patron | Ejemplo |
|---|---|---|
| URLs | http://, https:// | http://evil.com/gate.php |
| IPs | Formato IPv4 | 192.168.1.100, 45.33.32.156 |
| Dominios | Patron FQDN | c2server.evil.com |
| Rutas | C:, %TEMP%, %APPDATA% | C:\Users\Public\payload.exe |
| Registro | HKEY, CurrentVersion | HKCU\Software\Microsoft... |
| Comandos | cmd, powershell, wmic | cmd.exe /c whoami |
| DLLs | .dll | ws2_32.dll, advapi32.dll |
| APIs | Nombres de funciones | CreateRemoteThread |
| Mutex | Identificadores unicos | Global\MutexName123 |
| User-Agent | Mozilla, User-Agent | Mozilla/5.0 (Windows NT... |
| Credenciales | password, login, admin | admin:password123 |
Paso 5: Detect It Easy (DIE)
DIE identifica el compilador, linker y packer utilizado analizando patrones de bytes y heuristicas en el binario:
diec sample.exe
# Salida tipica:
# PE32
# Compiler: Microsoft Visual C/C++(2019)[EXE32]
# Linker: Microsoft Linker(14.29)
# Tool: Visual Studio(2019 version 16.11)
# O para un binario empaquetado:
# PE32
# Packer: UPX(3.96)[NRV2E]
Informacion que revela DIE:
- Compilador: MSVC, MinGW/GCC, Borland/Delphi, Go, Rust.
- Packer: UPX, ASPack, Themida, VMProtect, MPRESS.
- Installer: NSIS, Inno Setup, InstallShield.
- .NET: Si es un assembly .NET (para decompilacion con dnSpy/ILSpy).
Paso 6: PEStudio (analisis integral)
PEStudio es la herramienta de referencia para un analisis estatico rapido de PE. En una sola vista muestra:
| Seccion | Contenido |
|---|---|
| Indicators | Anomalias detectadas automaticamente |
| Virustotal | Resultado de busqueda del hash |
| Strings | Strings clasificadas por relevancia |
| Libraries | DLLs importadas |
| Imports | Funciones importadas con marcado de sospechosas |
| Exports | Funciones exportadas (si es DLL) |
| Resources | Recursos embebidos con entropia |
| Sections | Secciones con entropia y permisos |
| TLS | TLS callbacks (codigo pre-entry point) |
| Manifest | Manifest XML (permisos solicitados) |
| Version | Informacion de version del archivo |
| Certificate | Firma digital |
| Debug | Informacion de debug y rutas PDB |
Indicadores criticos que PEStudio resalta:
- Imports clasificadas como sospechosas (rojo)
- Secciones con entropia alta
- Entry point fuera de .text
- Timestamp anomalo
- Presencia de TLS callbacks
- Manifest solicitando elevacion de privilegios
Paso 7: Metadatos de compilacion
Compilador y version
El compilador deja huellas en el binario. Conocer el compilador ayuda a:
- Entender la estructura del codigo.
- Identificar funciones de runtime conocidas.
- Elegir el decompilador mas adecuado.
| Compilador | Indicadores |
|---|---|
| MSVC | Rich Header, CRT init code, secciones .CRT |
| MinGW/GCC | Seccion .textbss, sin Rich Header |
| Delphi/Borland | Seccion CODE, strings Delphi en recursos |
| Go | Strings runtime.main, gopclntab, buildid |
| Rust | Strings rust_begin_unwind, panic messages |
| .NET | CLR header, seccion .text con IL code |
| AutoIt | String "AU3!" en recursos, AutoIt3 script |
| PyInstaller | Seccion con overlay grande, archivos Python embebidos |
| NSIS | Secciones .ndata, .rsrc grande, strings NSIS |
Informacion de version
Los recursos de version (VS_VERSION_INFO) pueden contener:
- CompanyName, ProductName, FileDescription
- OriginalFilename (revelador si difiere del nombre actual)
- InternalName
- FileVersion, ProductVersion
El malware a veces copia la informacion de version de ejecutables legitimos para parecer autentico. Si un archivo dice ser de "Microsoft Corporation" pero no tiene firma digital de Microsoft, es sospechoso.
Paso 8: Verificacion de firma digital
# Windows (PowerShell)
Get-AuthenticodeSignature sample.exe
# Linux (con osslsigncode)
osslsigncode verify sample.exe
# Python
import pefile
pe = pefile.PE("sample.exe")
# Verificar si tiene Security Directory (Data Directory index 4)
if len(pe.OPTIONAL_HEADER.DATA_DIRECTORY) > 4:
sec_dir = pe.OPTIONAL_HEADER.DATA_DIRECTORY[4]
if sec_dir.VirtualAddress > 0 and sec_dir.Size > 0:
print("Tiene firma digital (verificar validez)")
else:
print("Sin firma digital")
| Escenario | Implicacion |
|---|---|
| Sin firma | Sospechoso si se presenta como software de empresa conocida |
| Firma valida de empresa desconocida | Verificar la empresa, podria ser certificado robado |
| Firma invalida o expirada | Firma removida, binario modificado post-firma |
| Firma de empresa conocida y valida | Podria ser legitimo o usar certificado robado |
Flujo completo de triaje
Aplicando todos los pasos en orden:
# 1. Tipo de archivo
file sample.suspicious
# 2. Hashes
sha256sum sample.suspicious
# 3. Buscar en VirusTotal (si la politica lo permite)
# vt hash search: sha256_del_archivo
# 4. Strings rapido
strings -n 6 sample.suspicious | head -50
strings -n 6 sample.suspicious | grep -iE "http|\.exe|cmd|HKEY"
# 5. FLOSS (si strings no revela mucho)
floss sample.suspicious --no-static-strings
# 6. Detectar compilador/packer
diec sample.suspicious
# 7. Entropia
python3 -c "
import pefile
pe = pefile.PE('sample.suspicious')
for s in pe.sections:
name = s.Name.decode().rstrip(chr(0))
print(name, round(s.get_entropy(), 2))
"
# 8. ssdeep para agrupar con muestras conocidas
ssdeep sample.suspicious
Tiempo estimado: 5 a 10 minutos para un triaje completo.
Automatizacion del triaje
import hashlib
import pefile
import sys
import os
def basic_triage(filepath):
# Tamano
size = os.path.getsize(filepath)
# Hashes
data = open(filepath, "rb").read()
md5 = hashlib.md5(data).hexdigest()
sha256 = hashlib.sha256(data).hexdigest()
print("=== Basic Triage Report ===")
print("File:", filepath)
print("Size:", size, "bytes")
print("MD5:", md5)
print("SHA256:", sha256)
print()
# PE analysis
try:
pe = pefile.PE(filepath)
except pefile.PEFormatError:
print("No es un PE valido")
return
# Tipo
is_dll = bool(pe.FILE_HEADER.Characteristics & 0x2000)
is_exe = bool(pe.FILE_HEADER.Characteristics & 0x0002)
arch = "x64" if pe.FILE_HEADER.Machine == 0x8664 else "x86"
print("Tipo:", ("DLL" if is_dll else "EXE"), arch)
print("ImpHash:", pe.get_imphash())
print()
# Secciones
print("Secciones:")
for s in pe.sections:
name = s.Name.decode().rstrip("\x00")
entropy = round(s.get_entropy(), 2)
flag = ""
if entropy > 7.0:
flag = " [HIGH ENTROPY]"
print(" " + name.ljust(12) + str(entropy) + flag)
# Imports count
import_count = 0
if hasattr(pe, "DIRECTORY_ENTRY_IMPORT"):
for entry in pe.DIRECTORY_ENTRY_IMPORT:
import_count += len(entry.imports)
print("\nImports:", import_count)
if import_count < 10:
print("[!] Pocas imports: probable resolucion dinamica o packing")
# Timestamp
import datetime
ts = pe.FILE_HEADER.TimeDateStamp
try:
compile_date = datetime.datetime.utcfromtimestamp(ts)
print("Compilado:", compile_date)
if compile_date.year > 2030 or compile_date.year < 2000:
print("[!] Timestamp sospechoso")
except (ValueError, OSError):
print("[!] Timestamp invalido:", hex(ts))
if __name__ == "__main__":
basic_triage(sys.argv[1])
Conclusion
El analisis estatico basico es el punto de partida obligatorio para cualquier muestra sospechosa. En menos de 10 minutos, un analista puede determinar el tipo de archivo, verificar si es conocido por la comunidad, extraer indicadores (strings, hashes, IPs, URLs), detectar si esta empaquetado y obtener metadatos del compilador. Estas herramientas (strings, FLOSS, PEStudio, DIE, ssdeep) son gratuitas y no requieren ejecutar el binario, eliminando cualquier riesgo de infeccion durante el triaje inicial.
Preguntas frecuentes
Libros recomendados
Artículos relacionados
Formato PE de Windows: Estructura Completa del Ejecutable
Entropia: Detectar Empaquetado y Cifrado en Binarios
Secciones PE: .text, .data, .rsrc, .reloc y Anomalias
Import Address Table: APIs Sospechosas y Resolucion Dinamica
Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.