- Strings filtra y muestra solo cadenas legibles en binarios, clave en forense y CTF.
- Opciones como -n, -e y -t ajustan longitud, codificación y offsets con precisión.
- Combinado con grep, sort, head y binwalk, acelera investigaciones complejas.
- Para proteger cadenas sensibles, valora cifrado en runtime y ofuscación ligera.
Cuando te pica la curiosidad técnica, pocos comandos dan tanta satisfacción como strings
. Esta pequeña utilidad es capaz de sacar a la luz texto legible escondido en medio de bytes, ya sea en ejecutables, bibliotecas o archivos aparentemente crípticos. Si trabajas con Linux, análisis forense, CTF o depuración de binarios, dominarla te ahorra horas.
En esta guía vamos a exprimir strings
de principio a fin: desde su uso básico hasta combinaciones potentes con otras herramientas, pasando por casos reales de esteganografía en texto, audio e imágenes, y consejos para desarrolladores que buscan evitar que sus cadenas sensibles queden expuestas en los binarios. Tendrás ejemplos claros y técnicas contrastadas para que le saques todo el partido.
Qué es strings y por qué es tan útil
El comando strings
examina un archivo y muestra únicamente las secuencias de caracteres imprimibles presentes en él. En binarios, donde abunda el ruido, esto filtra justo lo que te interesa: nombres, rutas, mensajes, firmas y pistas de ejecución.
¿Para qué lo usamos? Los motivos más habituales son claros: análisis forense, depuración y simple curiosidad técnica. En forense y respuesta a incidentes, ayuda a identificar artefactos (URLs, usuarios, comandos, rutas de instalación). En desarrollo, confirma si una cadena quedó incrustada, y en CTF es una navaja suiza para obtener referencias rápidas.
Un matiz clave: por defecto strings
busca cadenas ASCII de longitud mínima configurable. Esto evita que la salida esté llena de falsos positivos, aunque puede ajustarse a otros conjuntos de caracteres cuando el archivo lo requiere.
Primeros pasos: uso esencial del comando
La invocación más simple es directa. Si quieres listar todas las cadenas legibles en un binario llamado ejemplo.bin
:
strings ejemplo.bin
Por defecto la herramienta emite cualquier secuencia de caracteres imprimibles a partir de una longitud mínima. Ajustar esa longitud te permite eliminar ruido que no aporta y centrarte en mensajes de interés.
Por ejemplo, para mostrar solo cadenas de 10 o más caracteres, usa el modificador de longitud mínima: reduce drásticamente las coincidencias poco útiles.
strings -n 10 ejemplo.bin
También puedes pasar varios archivos a la vez. Es práctico cuando inspeccionas un conjunto de binarios (por ejemplo, una carpeta de ejecutables o bibliotecas):
strings archivo1.bin archivo2.bin archivo3.bin
Opciones y técnicas avanzadas para afinar resultados
Una primera optimización habitual es especificar la codificación. Por defecto se asume ASCII, pero si sospechas codificaciones distintas (8 bits, UTF-16LE/BE), el parámetro -e
resulta clave.
En implementaciones GNU de strings
, las banderas típicas de -e
incluyen: s
(7-bit), S
(8-bit), l
(16-bit little-endian), b
(16-bit big-endian), L
/B
(variantes). Un ejemplo buscando secuencias de 8 bits:
strings -e S archivo.bin
Cuando quieres saber dónde está cada cadena en el archivo, añade offsets. El modificador -t
permite elegir el formato del desplazamiento (decimal, octal, hexadecimal):
strings -t x archivo.bin
En binarios enormes, la salida puede ser abrumadora. Combinar con utilidades como head
, grep
, sort
o uniq
te devuelve el control. Por ejemplo, para mostrar solo las primeras 100 cadenas:
strings archivo_grande.bin | head -n 100
Para filtrar por una palabra clave (por ejemplo, “token”): encadena con grep
y limita el ruido:
strings -n 8 binario | grep -i token
Si necesitas ordenar y deduplicar resultados en investigaciones amplias, prueba: clasificar y eliminar duplicados ayuda a ver patrones.
strings binario | sort | uniq -c | sort -nr
Y si vas a conservar la salida, lo más portable es redirigir con el shell: la redirección con >
es universal y evita dependencias de implementación.
strings binario > cadenas.txt
Uso práctico en análisis forense
En un sistema comprometido, strings
acelera el reconocimiento de artefactos. De ejecutables sospechosos puedes extraer rutas, dominios, comandos y pistas de persistencia. Cruzar esos hallazgos con logs o IOC amplía la narrativa del incidente.
En bibliotecas compartidas, drivers o módulos, verás nombres de funciones y mensajes de error que te orientan sobre capacidades o partes activas. En cajas negras como firmware, ayuda a localizar marcas del fabricante o versiones internas.
Un consejo: si trabajas con múltiples piezas, agrega un campo de origen para cada cadena (por ejemplo, preponiendo el nombre de archivo con xargs
o usando herramientas que impriman origen) para poder pivotar después sin perder contexto.
Esteganografía en texto: lo invisible también habla
La esteganografía textual muchas veces se apoya en caracteres que “no vemos”. Revisar con lupa el tamaño real del texto y compararlo con lo visible destapa pistas inequívocas; puedes mostrar caracteres ocultos en Microsoft Office.
Una técnica clásica es ocultar bits usando espacios y tabuladores al final de cada línea. Si consideras espacio=0 y tab=1, puedes codificar mensajes binarios completos sin alterar el aspecto a simple vista.
Otra variante usa caracteres Unicode invisibles como Zero-Width Joiner/Non-Joiner. Estos signos no se aprecian visualmente pero ocupan lugar, lo que delata su presencia si cuentas caracteres.
También están los homoglifos: parecen la misma letra, pero son puntos de código distintos. Reemplazando letras por homoglifos, un texto aparentemente normal puede portar un mensaje paralelo.
Herramientas como CyberChef facilitan estos chequeos y técnicas para ocultar mensajes en documentos Word: miran longitud, líneas y caracteres no imprimibles. Si el recuento no cuadra con lo que ves, sospecha de estego textual.
Esteganografía en audio: pistas en el espectro y metadatos
En audio, es frecuente esconder información en el espectrograma. Imágenes o patrones aparecen al visualizar la densidad de frecuencias, sin que el oyente casual lo note.
Algunas pistas se alojan en canales separados. Escuchar o analizar cada canal por separado con Audacity o un editor similar revela mensajes que en mezcla pasan desapercibidos.
No olvides los metadatos (ID3, etc.). Campos de artista, álbum o comentarios pueden albergar texto clave. CyberChef te ayuda a inspeccionar etiquetas de forma rápida.
Para casos “ruidosos” que suenan a módem antiguo, mira herramientas como Audiotap o WAV-PRG. Ese chirrido podría ser un flujo de datos codificado para equipos retro o protocolos específicos.
Para análisis visual detallado del audio, Sonic Visualiser y SoX son aliados. Generar espectrogramas permite “ver” información que el oído no distingue.
Esteganografía en imágenes: canales, LSB y más
En imágenes raster, cada píxel suele tener cuatro componentes (R,G,B,A). Explorar canales por separado a veces deja a la vista texto oculto o símbolos que no se ven en la imagen compuesta.
Una técnica muy usada es modificar los bits menos significativos (LSB). Cambia muy poco el color, pero permite incrustar datos que luego se extraen con la clave o el algoritmo correcto.
Hay utilidades conocidas como steghide que permiten ocultar y extraer datos en imágenes (y audios) con contraseña. Stegsolve y Stegonline aplican filtros y ofrecen checklist específicos para CTFs.
En metadatos EXIF también pueden esconderse pistas: fechas, ubicaciones o comentarios con información relevante. No olvides revisarlos en la fase inicial.
Para fuerza bruta de contraseñas en archivos aptos para steghide, Stegseek acelera muchísimo. Si sospechas contraseñas débiles, es una vía rápida para validar o descartar esa hipótesis.
Estego en “otros” archivos y extra: binwalk y friends
Más allá de imágenes o audio, el truco de “pegar” archivos al final de otro contenedor es habitual. Binwalk identifica firmas y extrae artefactos embebidos con un par de flags bien elegidos.
Otra táctica consiste en meter datos brutos entre bloques útiles de un archivo. Un ojo hex y búsquedas de patrones (Base64, cabeceras, flags) detectan estas inyecciones con relativa facilidad.
Ojo con los falsos positivos: especialmente en PNG o binarios grandes, binwalk puede cantar coincidencias que en realidad son ruido. Contrasta con otros indicadores antes de sacar conclusiones.
En estas situaciones, strings
vuelve a ser útil: extrae texto legible que actúa como “hilo” del que tirar para descubrir qué hay detrás o dónde mirar con más detalle.
Combina strings con el resto del ecosistema Unix
La potencia real llega al encadenarlo. Por ejemplo, para etiquetar cada cadena con su origen al analizar varios binarios: usa bucles del shell o find
+ xargs
para mantener el contexto.
Si tienes que priorizar, agrupa, cuenta y ordena resultados con sort
y uniq -c
. Ver qué cadenas se repiten más te guía hacia trozos críticos de código o configuración.
Para informes rápidos, vuelca resultados a un archivo y comparte. Una simple redirección y un grep posterior facilitan el trabajo en equipo y la revisión.
Y cuando te importe el offset, recuerda que con -t
puedes sacar desplazamientos en hex o decimal, útiles para cruzar con desensamblados o volcados hexdump.
Cuando NO quieres que tus cadenas aparezcan: visión desde desarrollo
Muchas empresas registran internamente nombres de funciones o detalles de algoritmos y no quieren que queden a la vista. Si esas cadenas están en texto plano en el binario, strings
las delatará. ¿Qué se puede hacer?
Una idea es “hashing” en tiempo de compilación (plantillas, literales UDL). Reduce exposición directa pero puede disparar tiempos de compilación y complicar la portabilidad si dependes de compiladores antiguos (por ejemplo, VS2013 con soporte limitado de C++14).
Otra propuesta es almacenar datos como arrays de char
u octetos en hexadecimal. Puede engañar a búsquedas triviales con strings
, pero sigue dejando huella y complica el mantenimiento del código.
También existe el parcheo postcompilación para cifrar cadenas y descifrarlas en tiempo de ejecución. El reto está en preservar la integridad del ejecutable y la estabilidad en todas las plataformas objetivo.
Consejo realista: si no puedes depender de un servidor para traer cadenas bajo demanda, aplica descifrado en tiempo de ejecución con claves derivadas y ofuscación ligera (por ejemplo, dividir cadenas, decodificarlas en stack, liberar memoria enseguida). Ninguna técnica es infalible, pero sube el listón.
Sea cual sea la estrategia, valora el coste: tiempos de build, complejidad, compatibilidad multiplataforma y rendimiento. En muchos productos, un equilibrio práctico vale más que una solución “perfecta” difícil de mantener.
Trabajar con binarios sin romper nada: C++ y Java
Si necesitas leer o escribir binarios para analizarlos o transformarlos, evita tropiezos básicos. En C++ abre siempre con std::ios::binary
, dimensiona buffers correctamente y comprueba retornos de lectura. En entornos Windows revisa cómo manipular archivos desde CMD.
Los fallos de segmentación típicos vienen por usar punteros sin memoria válida, leer más bytes de los que caben en el buffer o interpretar estructuras con tamaños/alineamientos distintos a los reales.
Si serializas struct
y luego quieres mapearlos a clases, cuida padding y endianness. Es seguro leer a un std::vector<std::byte>
y parsear conscientemente, en vez de castear a ciegas.
En Java, para texto, FileReader
+ BufferedReader
funcionan bien; try-with-resources te asegura el cierre aunque haya excepciones. También puedes ir con Files.lines()
o Files.newBufferedReader()
indicando el charset correcto.
Para escribir texto, FileWriter
y PrintWriter
simplifican el formato de líneas. Con NIO, Files.newBufferedWriter()
te da control de charset y opciones como APPEND
o WRITE
.
En binario, usa FileInputStream
/FileOutputStream
o sus versiones con buffer. Lee a trozos, respeta el número de bytes realmente leídos y escribe solo esa longitud para evitar basura o truncados.
La clase RandomAccessFile
te permite saltar a posiciones concretas. Es muy útil cuando conoces offsets (por ejemplo, los impresos por strings -t
) y quieres editar o extraer segmentos puntuales.
Un apunte de rendimiento: operar con buffers amortigua I/O y acelera todo. BufferedInputStream
/BufferedOutputStream
reducen accesos físicos a disco, algo crucial con ficheros grandes.
Consejos prácticos y pequeños trucos con strings
Sube la longitud mínima cuando el binario sea muy ruidoso. Un -n 8
o -n 12
filtra cadenas poco informativas manteniendo los mensajes relevantes.
Al mirar malware o binarios ofuscados, prueba codificaciones de 16 bits. El texto puede estar alternando bytes nulos (UTF-16LE/BE) y así pasa desapercibido en ASCII puro.
Si una cadena es crítica, busca su offset y examina el contexto con xxd
o hexdump
. Ver bytes alrededor aclara si hay estructura o delimitadores útiles para extracción precisa.
En informes, incluye ejemplos de salida con offsets y muestras filtradas. Es más fácil que otro analista reproduzca y ampliar la investigación cuando dejas ese rastro.
Para pipelines reproducibles, anota las versiones de herramientas. Pequeñas diferencias de implementación (por ejemplo, variantes de -e
) explican salidas distintas entre equipos.
Algunas suites empaquetan funciones similares a strings
en Windows (por ejemplo, utilidades conocidas de terceros). Si operas en entornos mixtos, revisa compatibilidades y sintaxis para evitar sorpresas.
Con esteganografía, alterna inspección manual y herramientas automáticas. CyberChef para texto/metadatos, SoX o Sonic Visualiser para audio, y steghide/stegsolve para imágenes cubren la mayoría de escenarios comunes.
Cuando binwalk reporte demasiados hallazgos en PNG o binarios enormes, contrasta. Vuelve a strings
para buscar firmas, nombres o rutas plausibles antes de extraer a ciegas.
Todo lo anterior converge en una idea simple: strings
es el primer vistazo rápido y barato. Si ahí no hay nada, probablemente necesites técnicas más profundas, pero si sí aparece información, ya tienes por dónde empezar.
Después de recorrer opciones, combinaciones y escenarios (forense, CTF, desarrollo y estego), queda claro que entender bien strings
multiplica su utilidad. Usarlo con criterio, ajustar codificaciones y longitud, y apoyarlo en el resto del ecosistema te permite extraer valor de casi cualquier binario sin morir en el intento.
Redactor apasionado del mundo de los bytes y la tecnología en general. Me encanta compartir mis conocimientos a través de la escritura, y eso es lo que haré en este blog, mostrarte todo lo más interesante sobre gadgets, software, hardware, tendencias tecnológicas, y más. Mi objetivo es ayudarte a navegar por el mundo digital de forma sencilla y entretenida.