Take an overview #CTF #Forensics – Stranger Strings

Buenas a todos! Os presento un conjunto de entradas que iré publicando poco a poco sobre procedimientos y resoluciones de retos de Forense (a partir de ahora Forensics), de diferentes CTF.

La intencionalidad es compartir mi experiencia y dificultades que me he ido encontrado, con un punto de vista personal «mi primera vez» style (BobtheDog :P) y lo más didactico posible consultando toda la información en la red. Me he basado en esta página de Github donde estan colgados todos los CTF de los últimos años, como base de información.

Lo que viene a continuación y en otras entradas, no son resoluciones de write-ups, básicamente procedimientos a la hora de afrontar un CTF de Forensics. La complejidad de los CTF implica que cada uno de los retos sean diferentes uno de los otros, por tanto la manera de obtener fluidez, es realizar gran cantidad de ellos y tener automatizado un esquema medianamente parecido para todos, al comenzar a hacerlos.

Cuando nos dan un fichero, de forma automática (o la mayoría de las veces) procedo a usar el comando Strings. Nos permite principalmente determinar el contenido de ficheros que no son de texto (.txt), por ejemplo ficheros de tipo pcap, pdf, png, jpg, img, raw etc…

Para filtrar el contenido de la salida de la ejecución de strings podemos hacer uso de «pipelines» transformando un flujo de datos en un proceso comprendido por varias fases secuenciales, siendo la entrada de cada una la salida de la anterior, y así ir conectando distintos comandos. Un ejemplo sería el uso de comandos como grep, more, sort, tr, cut, uniq etc…Lo veremos más adelante.

Usamos strings nombre_fichero y filtramos por el nombre del CTF, para ver alguna coincidencia y así encontrar nuestra flag. ¿Fácil? Lo es, pero no son todos así. Grep es un comando que lee la entrada estándar o una lista de archivos, e imprime las líneas que contengan coincidencias para la expresión regular.

4
Figura 1

Dado por ejemplo un pcapng, podemos perfectamente hacer strings fichero | grep flag, y teniendo suerte obtener la flag. Ejemplo parecido al anterior:

11
Figura 2

 

53
Figura 3

 

36
Figura 4

Cuando la salida de strings nos dan un base64, podemos decodearlo con el comando base64 -d. Base64 se considera como un sistema de codificación de binario a texto que representa los datos binarios mediante una cadena ASCII, traduciéndolos en una representación de 64 caracteres. Frecuentemente la representación termina como ‘=’, dependiendo de la especificación usada ya sea (MIME, UTF-7, OpenPGP, etc..). Un ejemplo programatico en Python (Wikipedia):

>>> import base64
>>> texto = "Prueba de codificación BASE64!"
>>> textoCodificado = base64.encodestring(texto)
>>> textoCodificado
'UHJ1ZWJhIGRlIGNvZGlmaWNhY2nDs24gQkFTRTY0IQ==\n'
>>> base64.decodestring(textoCodificado)
'Prueba de codificación BASE64!'

O podemos hacerlo de esta forma, usando el comando echo para visualizar una cadena de carácteres, y filtrando la salida con «pipelines» como entrada al comando base64 -d.

35
Figura 5

Si la salida del comando Strings nos da un base64 al reves, podemos seguir este procedimiento usando rev para invertir el orden de la entrada de datos (carácteres).

54
Figura 6
55
Figura 7

Nos dan una dirección IP, hacemos una petición HTTP con curl y obtenemos la flag.

En la Figura 8, filtramos de forma paginada debido a la gran cantidad de lineas que devuelve con more. Identificamos un código en Python.

18

19
Figura 8

Tan solo necesitamos la salida de print, devolviendo la salida de una base64. Por ello recomiendo usar la opción -a para poder encontrar el base64. Una vez localizado, simplemente usando el procedimiento de la Figura 5, nos sería suficiente para encontrar la flag.

En el siguiente ejemplo, usamos el comando tail para visualizar las 10 últimas lineas del .img, filtrando de nuevo y pasando como entrada a grep. Con el parametro -i indicamos que ignore entre mayusculas y minusculas.

77
Figura 9

Tenemos un dump de VMware. Una forma de filtrar los perfiles, en vez de usar Volatility, podemos usar Strings. No nos sugiere el perfil exacto, pero es bastante orientativo, y podemos seguir filtrando del mismo modo. Filtramos y con los parámetros -iEo, indicamos que no exista distinción entre mayúsculas y minúsculas, permitir el uso de expresiones regulares, y que la salida del comando debe contener sólo el texto que coincide con el patrón. Sort nos permite mostrar la salida ordenada, y con uniq -c agrega un prefijo a las líneas con el número de ocurrencias. Dependiendo del número deducimos que el sistema operativo usado es Linux (distribución Debian).

79
Figura 10
80
Figura 11

Como hemos visto anteriormente, sólo hemos usado el comando Strings para poder resolver los retos y obtener las flags de manera inmediata, sin tener que usar otras herramientas (excepto con los filtros «pipelines») para poder buscar la flag. Por tanto, son retos fáciles. En las siguientes entradas usaremos este comando en pocas ocasiones, y nos centraremos en procedimientos distintos dependiendo de la dificultad del mismo.

 

Un saludo, Naivenom.