Write-ups del Cybercamp 2018: Medium (parte 2)
En el post anterior sólo incluí los retos 5 y 6. Como ya ha pasado mucho tiempo, he decidido escribir una segunda parte con el resto de los retos medium
Cada año, el INCIBE (una agencia española que se encarga de concienciar sobre temas de ciberseguridad) organiza la CyberCamp.
Estos son los write-ups de los clasificatorios del CTF, que fueron hace ya un par de semanas. Como los resultados ya se han anunciado1 y han dicho que podemos subir nuestros write-ups, estoy escribiendo aquí mis soluciones para los retos que resolví. Los materiales para los de este post se pueden descargar aquí:
En este artículo explicaré mis respuestas para los retos etiquetados como medium.
7.- Vacaciones
La descripción de este reto dice así:
Por orden de un juez, se ha intervenido un equipo en casa de un sospechoso
ciberdelincuente, por suerte su portátil aún se encontraba encendido cuando se produjo la
detención. Se sabe que ha intentado eliminar pruebas, pero creemos que aún es posible
obtener alguna. ¿Cuál era su nick en la red? (Respuesta: flag{NICK}).
Se nos dan dos archivos:
- dump.elf
: un ejecutable (ELF) de 64-bit
- volume.bin
: una imagen de un disco
Vamos a empezar montando la imagen del disco para ver si podemos encontrar algo. Lo
primero que debemos hacer al montar una imagen es buscar el desplazamiento necesario
de la partición que queremos explorar. Para esto, fdisk -l
viene muy útil:
$ fdisk -l volume.bin
Disk volume.bin: 64 MiB, 67108864 bytes, 131072 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Sectors Size Id Type
volume.bin1 63 16064 16002 7.8M 83 Linux
Hay que tener en cuenta el valor de start y multiplicarlo por 512, porque ese es el
tamaño de un sector y mount
espera Bytes, no sectores; así que para montar la
imagen habrá que usar la siguiente orden:
$ sudo mount -o offset=32256 volume.bin mnt/
mount: ./mnt: unknown filesystem type 'crypto_LUKS'.
Oh, vaya… Parece que no va a ser tan fácil :( El volumen está cifrado con LUKS. Para montarlo vamos a tener que averiguar la contraseña o sacarla de algún lado.
Vamos a echarle un vistazo al otro archivo, dump.elf
.
A primera vista, parece un ejecutable de 64-bit normal. Tiene las cabeceras correctas
para engañar a file
. Sin embargo, si miramos más de cerca, podemos ver que contiene
muchas cosas, empezando por un ejecutable de 64-bit. Por ejemplo, con
binwalk extraemos muchísimas cosas:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ELF, 64-bit LSB core file AMD x86-64, version 1 (SYSV)
48047 0xBBAF Copyright string: "Copyright (C) 1994-2015 H. Peter Anvin et al"
935207 0xE4527 Copyright string: "Copyright (C) 1997-2000 Intel Corporation"
935250 0xE4552 Copyright string: "Copyright (C) 2010-2017 Oracle Corporation"
1058104 0x102538 gzip compressed data, maximum compression, from Unix, NULL date (1970-01-01 00:00:00)
7094968 0x6C42B8 gzip compressed data, maximum compression, from Unix, NULL date (1970-01-01 00:00:00)
21275960 0x144A538 gzip compressed data, maximum compression, from Unix, NULL date (1970-01-01 00:00:00)
24771468 0x179FB8C ELF, 32-bit LSB executable, Intel 80386, version 1 (SYSV)
87520568 0x5377538 Linux kernel version "4.14.52-0-virt (buildozer@build-3-8-x86) (gcc version 6.4.0 (Alpine 6.4.0)) #1-Alpine SMP Tue Jun 26 07:14:31 UTC 2018"
87654648 0x53980F8 CRC32 polynomial table, little endian
88712398 0x549A4CE Unix path: /home/buildozer/aports/main/linux-vanilla/src/linux-4.14/init/main.c
(...)
Parece que es algún tipo de volcado. ¿Quizá sea de la memoria, donde pueden estar las claves para descifrar el disco? Vamos a usar findaes para buscar claves de AES (LUKS normalmente usa AES):
$ ./findaes ../../dump.elf
Searching ../../dump.elf
Found AES-256 key schedule at offset 0xe414ce8:
0a b4 d6 ef 72 82 6b c6 03 a8 89 9f 32 5b b6 7e 9b 32 41 77 1c fd 03 30 56 9a ce ab 16 f2 51 bd
Found AES-128 key schedule at offset 0xe4158f8:
84 bc d9 8c fc f2 de db 26 06 35 bf ca a9 a4 7d
Et voilà, tenemos dos posibles candidatos. Tendremos que esperar un poco para saber cuál tendremos que usar.
Como la herramienta para descifrar la partición espera que la imagen sea un dispositivo
(un archivo de tipo device) y en el reto nos han dado un archivo regular, tenemos que
realizar una conversión primero. En los sistemas de tipo Unix todo es un archivo, y los
dispositivos (discos, teclados, micrófonos…) no son una excepción. Sin embargo, hay
diferentes tipos de archivos (tuberías, archivos regulares, sockets…). Para convertir
un archivo regular en un dispositivo usamos el dispositivo loop, usando la
herramienta losetup
. Tras ejecutar sudo losetup /dev/loop0 volume.bin -o 32256
(hay
que recordar que queremos descifrar la partición que empieza en el sector 64) podemos
seguir trabajando con /dev/loop0
.
Ahora que tenemos lista la partición, podemos usar la herramienta cryptsetup
para
obtener más información sobre la clave que deberíamos usar:
$ sudo cryptsetup luksDump /dev/loop0
LUKS header information for /dev/loop0
Version: 1
Cipher name: aes
Cipher mode: cbc-essiv:sha256
Hash spec: sha256
Payload offset: 2048
MK bits: 128
(...)
Así que es AES-128. Bien, usemos la clave que hemos sacado antes:
$ printf "84 bc d9 8c fc f2 de db 26 06 35 bf ca a9 a4 7d" | tr -d ' ' | xxd -r -ps > key_file
$ sudo cryptsetup open /dev/loop0 cybercamp-7-decrypted --master-key-file key_file
$ sudo mount /dev/mapper/cybercamp-7-decrypted mnt/
$ ls -a mnt/
. ..
Rayos, esto es un poco incómodo… Estaba esperando sacar algo de aquí, pero está vacío. ¿O quizá no?
Hmmmm…
Sabemos que el criminal intentó borrar algunas pruebas, así que puede que borrara el
contenido del disco pero en realidad sigan ahí. Si los archivos no han sido sobrescritos,
puede que aún sean recuperables. Hay muchas herramientas para recuperar archivos
“borrados”. Una de ellas es scalpel. Una vez
ha terminado su trabajo, nos deja con un .zip que parece estar cifrado, porque file
devuelve Zip archive data, at least v1.0 to extract
.
Como siempre, tenemos muchas formas de recuperar la contraseña; pero yo voy a usar John
The Ripper debido a la multitud de herramientas disponibles para convertir de cualquier
formato al que usa JTR. En este caso, usamos zip2john
para obtener el hash y luego
ejecutamos john <archivo_hash>
. En un par de segundos extrae la contraseña: iloveyou
.
Luego extraemos el archivo comprimido (con 7z
, ya que unzip
no sabe manejar los
archivos con contraseña) y vemos el contenido del archivo que estaba comprimido:
$ cat secret.txt
_z3r0.c00l!_ was here! :)
Pues ya hemos recuperado el nick, buen trabajo.
La flag es flag{z3r0.c00l!}
8.- Oh, my GOd!
La descripción de este reto dice así:
Se ha interceptado un código en la conversación entre dos delincuentes cuyo
funcionamiento tendrás que averiguar para llegar a la FLAG.
Este reto es bastante más sencillo que el resto de los de este nivel, y sólo involucra
un archivo de bytecode de Python, medium_8.pyc
.
Podemos intentar importarlo en el intérprete de Python; pero no es aconsejable ejecutar sin más cualquier código sin antes inspeccionarlo, especialmente en un CTF donde lo más probable es que haya que hacerlo igualmente…
Para decompilar el bytecode de Python2 usé pycdc, que es sencillo de usar y funciona bastante bien:
$ pycdc medium_8.pyc
# Source Generated with Decompyle++
# File: medium_8.pyc (Python 2.7)
print '$$$$$$$$$ ^-^ \xe2\x95\xa6 \xe2\x95\xa6\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\xac \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\x8c\xe2\x94\xac\xe2\x94\x90\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\xac\xe2\x94\x90\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\xac\xe2\x94\x90\xe2\x94\xac \xe2\x94\xac\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\xac \xe2\x94\xac\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\xac \xe2\x94\xac \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\x8c\xe2\x94\x90\xe2\x94\x8c\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x90'
print ' \xe2\x95\x91\xe2\x95\x91\xe2\x95\x91\xe2\x94\x9c\xe2\x94\xa4 \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82\xe2\x94\x82\xe2\x94\x82\xe2\x94\x82\xe2\x94\x9c\xe2\x94\xa4 \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\xa4\xe2\x94\x9c\xe2\x94\xa4 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\xa4\xe2\x94\x9c\xe2\x94\x80\xe2\x94\xa4\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\xa4 \xe2\x94\x82\xe2\x94\x82\xe2\x94\x82\xe2\x94\x82 \xe2\x94\xac\xe2\x94\x9c\xe2\x94\xa4 '
print ' \xe2\x95\x9a\xe2\x95\xa9\xe2\x95\x9d\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x98\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98\xe2\x94\xb4 \xe2\x94\xb4\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98 \xe2\x94\xb4 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x98 \xe2\x94\xb4 \xe2\x94\xb4 \xe2\x94\xb4\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x98\xe2\x94\xb4 \xe2\x94\xb4\xe2\x94\xb4 \xe2\x94\xb4\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x98\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x98\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98\xe2\x94\x98\xe2\x94\x94\xe2\x94\x98\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98\xe2\x94\x94\xe2\x94\x80\xe2\x94\x98'
print ' ^-^ $$$$$$$$$$'
import md5
SHA1 = [
0xBA4439EE9A46D9D9F14C60F88F45F87L,
0xDB0F6F37EBEB6EA09489124345AF2A45L,
0x52A8CBE3663CD6772338701016AFD2DFL,
0x56AB24C15B72A457069C5EA42FCFC640L,
0xB61A6D542F9036550BA9C401C80F00EFL]
print 'If you are a good programer you know what you need to do to read the script'
Flag = raw_input('Please enter the flags: ')
if len(Flag) > 25:
print 'The flag is to long'
exit()
if len(Flag) % 5 != 0:
print 'The flag is to short'
exit()
if len(Flag) == 0:
print 'Please enter the Flags'
exit()
for r00t in range(0, len(Flag), 5):
z3r0 = Flag[r00t:r00t + 5]
if int('0x' + md5.new(z3r0).hexdigest(), 16) != SHA1[r00t / 5]:
print 'try harder the next time'
exit()
continue
if len(Flag) == 25:
print 'The Flag Is : ', Flag
exit()
exit()
if len(Flag) / 25 != '0b1'[2:]:
print 'try with binary'
exit()
Este código de Python 2 es bastante sencillo de entender: pide al usuario que
introduzca algo por pantalla, Flag
, que debe tener 25 caracteres y luego realiza alguna
comprobación en un bucle. En este bucle se extraen de Flag
trozos de 5 caracteres.
Luego comprueba que el MD5 de este cacho es igual que un hash hardcodeado, los que se
almacenan en la variable SHA1
(el nombre es obviamente una distracción, porque
claramente se está usando el módulo md5
).
Al final, la respuesta es la concatenación de cinco palabras de cinco caracteres con un hash en particular.
Al final el reto consiste simplemente en crackear estos hashes para obtener la flag. O, incluso mejor, usar alguna de las muchas bases de datos que hay disponibles por Internet. Después de buscar en un par de ellas, llegamos rápidamente al resultado (ordenado de la misma forma en la que se comprueban):
0ba4439ee9a46d9d9f14c60f88f45f87 MD5 : check
db0f6f37ebeb6ea09489124345af2a45 MD5 : group
52a8cbe3663cd6772338701016afd2df MD5 : zezex
56ab24c15b72a457069c5ea42fcfc640 MD5 : happy
b61a6d542f9036550ba9c401c80f00ef MD5 : tests
Fácil, ¿verdad? :)
La flag es checkgroupzezexhappytests
.
9.- Monkey Island
La descripción de este reto dice así:
Se ha incautado un equipo perteneciente al miembro de una APT, tras un profundo análisis
forense no se han podido obtener evidencias que hayan sido eliminadas o cifradas, en el
contenido más significativo del delincuente se ha recuperado un video que sospechan que
pueda contener algún tipo de prueba delictiva. (La flag es sensible a mayus/minus)
La primera cosa que suelo hacer con archivos de este tipo (películas, audio…) en los
CTFs, incluso antes de leer la descripción, es usar binwalk
. Esconder un archivo dentro
de otro simplemente concatenándolos es una técnica tan usada (al menos en los CTFs) que
lo hago casi por instinto :D
No siempre encuentra algo; pero esta vez sí:
$ binwalk MonkeyIsland.avi
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
26013116 0x18CEDBC Zip archive data, at least v2.0 to extract, compressed size: 613, uncompressed size: 811, name: bandera64.txt
26013883 0x18CF0BB End of Zip archive
El zip extraído contiene un archivo de texto con algunos datos codificados en base64:
$ cat bandera64.txt
UEsDBAoACQBjALpE5UyE1fPolAEAAHgBAAALAAsAYmFuZGVyYS5wbmcBmQcAAQBBRQMAAPKu8K6x
c7GJh/VmKva+f8JqD7Pe3X95ttenp+LwVVKiTrs1N450IIK7cjKsIYwqYBWiSwcClH2S51vh+L6/
xnICJFdIYuqD+sB282j0guUmoXbdIwU3dMtkYeUs/tOm7yd4TxHMfEQ2wM+i64R/iuhx9xvvh5PV
jnyPiKnjKPTQf9tH1XflKezQ8lHDAFPeEWZSMlRBaOwVWLywkiopyEYSuJGzJchCoRtiMX3fmfJX
8bD3SozBFIOPMjje/3/Xn6tVdmaaAVpAt8+iXu05VwXmmg8Ub7isi2KJBljiGMTQ+knFndW3gCEr
V3pk1OfNOGWAI09l5QXe6I+UKJZ5p9bpLi0fBbTHJCFcFu5y/IJHr9Vr5rzi6vpPU7p0ZtNJyYoK
EUB18DsmONtxc+xuqloJtzhRUQ5ZHRWumnfMk9Cw1tYT/KHa4gWh/GOVHLEAkizskRobAfanZ0OY
TfmYtjl/60UaL/sFkDYH4+uNt9MKLLiLR4WomoTq2Qi4o+EyzLDO0drgZXjsd1aN9s3EYkNY+Ug6
UEsHCITV8+iUAQAAeAEAAFBLAQIfAAoACQBjALpE5UyE1fPolAEAAHgBAAALAC8AAAAAAAAAIAAA
AAAAAABiYW5kZXJhLnBuZwoAIAAAAAAAAQAYAABwYYR+FNQBD0sSrJY51AHbTw9ChznUAQGZBwAB
AEFFAwAAUEsFBgAAAAABAAEAaAAAANgBAAAAAA==
Su nombre, bandera64, sugiere que si decodificamos en base64 obtendremos la bandera. Vamos a ver si es verdad:
$ base64 -d bandera64.txt > decoded
$ file decoded
decoded: Zip archive data, at least v1.0 to extract
Rayos, es un Zip cifrado. Pero no es la primera vez que nos encontramos uno de estos. ¿Recuerdas el 7º reto?
Usemos otra vez las mismas herramientas (zip2john
y john
) para intentar sacar la
contraseña. No tenemos ninguna pista de cuál puede ser, así que empezaremos como siempre,
probando primero los diccionarios comunes (/usr/share/dict/words
, rockyou
…). Con
nuestro primer intento ya sacamos la contraseña: grog
.
De este zip extraemos un archivo llamado bandera.png. Pero soy incapaz de saber qué significa esto:
¿Es esta la flag? ¿Cómo meto la solución en la página del CTF?
Estaba bastante perdido con este paso final, así que decidí coger una pista de la página:
El segundo mensaje se ha ocultado con el lenguaje de programación PIET
https://gabriellesc.github.io/piet/
Vale, la verdad es que esta pista fue bastante útil. Ahora es simplemente hay que subir
esta imagen al intérprete que se da en la pista y ejecutarlo. El código imprime el
mensaje THESevenSamurai
, que resulta que es la solución.
Finalmente, la flag es THESevenSamurai
.
9.- Chicken Dinner
La descripción de este reto dice así:
Se sospecha que un compañero de tu oficina está vendiendo secretos de estado a través de
una aplicación de mensajería muy utilizada. Se te ha proporcionado la imagen de su
terminal Android a través del cual deberás recuperar y localizar estos mensajes. En ellos
se encontrará la FLAG que necesitas.
Para empezar este reto, vamos a montar la imagen y a empezar navegando en el sistema de
archivos un poco. Recuerda que hay que mirar el desplazamiento de la partición usando
fdisk -l
y luego hay que multiplicar lo que salga por el tamaño de un sector (512
Bytes) para decirle a mount
cuál es el desplazamiento correcto.
Como estamos intentando encontrar mensajes borrados, necesitamos localizar las aplicaciones que se hayan podido utilizar. En este caso, encontramos cuatro: - WhatsApp - Telegram - Facebook Messenger - Instagram
De estas cuatro, sólo los directorios de Instagram y WhatsApp tienen algo. La de Instagram, sin embargo, parece que sólo tiene algunas preferencias locales y la caché, pero ninguna base de datos que parezca que pueda tener mensajes; así que vamos a echarle un vistazo a WhatsApp.
Este es el contenido del directorio de WhatsApp:
android-6.0-rc1/data/data/com.whatsapp/
├── app_minidumps
├── cache
├── databases
│ ├── _jobqueue-WhatsAppJobManager
│ └── _jobqueue-WhatsAppJobManager-journal
├── files
│ ├── Avatars
│ ├── key
│ ├── Logs
│ │ └── whatsapp.log
│ ├── rc2
│ ├── statistics
│ ├── .trash
│ └── wam.wam
├── no_backup
│ └── com.google.android.gms.appid-no-backup
└── shared_prefs
├── com.google.android.gms.appid.xml
├── com.google.android.gms.measurement.prefs.xml
├── com.whatsapp_preferences.xml
├── _has_set_default_values.xml
├── keystore.xml
└── qr_data.xml
Desafortunadamente, no hay nada por aquí. Las únicas bases de datos que hay parecen tener cosas de la configuración, pero ningún mensaje. Pero parece que hay un archivo que se llama key que puede ser útil en el futuro…
Otro lugar en el que podemos mirar es en el directorio de datos del usuario, en
/android-6.0-rc1/data/media
:
data/media
├── 0
├── DCIM
│ ├── Camera
│ ├── Screenshots
│ └── .thumbnails
├── obb
└── WhatsApp
├── Databases
│ └── msgstore.db.crypt12
├── Media
│ ├── WallPaper
│ ├── WhatsApp Animated Gifs
│ │ ├── Private
│ │ │ └── .nomedia
│ │ └── Sent
│ │ └── .nomedia
│ ├── WhatsApp Audio
│ │ ├── Private
│ │ │ └── .nomedia
│ │ └── Sent
│ │ └── .nomedia
│ ├── WhatsApp Documents
│ │ ├── Private
│ │ │ └── .nomedia
│ │ └── Sent
│ │ └── .nomedia
│ ├── WhatsApp Images
│ │ ├── Private
│ │ │ └── .nomedia
│ │ └── Sent
│ │ └── .nomedia
│ ├── WhatsApp Profile Photos
│ ├── WhatsApp Stickers
│ │ └── .nomedia
│ ├── WhatsApp Video
│ │ ├── Private
│ │ │ └── .nomedia
│ │ └── Sent
│ │ └── .nomedia
│ └── WhatsApp Voice Notes
│ ├── 201815
│ │ └── .nomedia
│ └── .nomedia
├── .Shared
└── .trash
¡Bingo! Bueno, más o menos… Podemos ver que hay un archivo llamado msgstore.db… Con una extensión crypt12 :(
Aunque una extensión por sí misma no significa nada, un vistazo rápido a las cabeceras nos dicen que el archivo está cifrado. Pese a esto, hay muchas herramientas por ahí que te permiten descifrarlo, suponiendo que tienes la clave. Yo decidí usar WhatsApp-Crypt12-Decrypter sin más razón que fue el primer resultado que apareció en DuckDuckGo cuando lo busqué.
Como nota aparte, encontré este otro repo donde se explica el modo de funcionamiento de Crypt12 (AES-GCM, básicamente), lo que me parece bastante interesante.
Este usuario, @mgp25, tiene también otras cosas muy interesantes. Os recomiendo echarle un vistazo a sus otros proyectos.
Volviendo al reto, ¿recordáis aquél archivo llamado key que vimos antes? Quizá podamos usarlo aquí:
$ java -jar decrypt12.jar ../key ../msgstore.db.crypt12 decrypted.db
Decryption of crypt12 file was successful.
$ file decrypted.db
decrypted.db: SQLite 3.x database, user version 1, last written using SQLite version 3011000
Genial, esto marcha bien. Ahora es el momento de examinar el contenido de la BDD. Hay varias tablas; pero la que más nos llama la atención es la que se llama messages. Efectivamente, ahí hay varios mensajes intercambiados. Esta es la transcripción, siendo A el propietario del dispositivo y B el otro extremo de la conversación, +34 628 205 625:
A: Hey!! Are u online? I think they have discovered me…
A: This is my last message…i want my money
A: And the chicken dinner…u know what it is
B: Ok no problem…
B: Send me the chicken dinner now and delete this conversation
A: Ok, 1min, need to encode it
A: iVBORw0KGgoAAAANSUhEUgAAAyAAAAJYCAYAAACadoJwAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBI WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gYZCggdk0GemwAAAAxpVFh0Q29tbWVudAAAAAAAvK6y mQAAIABJREFUeNrt3XmYFOWB+PFihhkchmtAkGNUDkWBcHjhgRxmAwRJsoqKqNldo0TDk6BBIIJB o+IK67UadReIiTGiuBFcg7qocQHlkM0DCowrXly6HAqogNzj8/7++D36JE4VzMB093TP5/M89QfD AQAABAgAAIAAAQAABAgAACBAAAAABAgAACBAAAAABAgAACBAAAAAAQIAACBAAAAAAQIAACBAAAAA (…) AAAQIAAAgAABAAAQIAAAgAABAAAQIAAAgAABAAAECAAAgAABAAAECAAAgAABAAAECAAAIEAAAAAE CAAAIEAAAAAECAAAIEAAAAABAgAAIEAAAAABAgAAIEAAAAABAgAACBAAAAABAgAACBAAAAABAgAA CBAAAECAAAAACBAAAECAAAAACBAAAECAAAAACBAAAECAAAAAAgQAAECAAAAANd//AyfU84FIjoOV AAAAAElFTkSuQmCC
A: This is my last message, send me the money on the same account
B: Ok…
Esa cadena tan larga es demasiado sospechosa y tiene pinta de ser base64. De hecho, si la extraemos y decodificamos, acabamos con una imagen PNG que contiene la respuesta:
Y ya hemos acabado.
La flag es TOO_MANY_SECRETS
.
10.- La Orden del Temple
La descripción de este reto dice así:
Se incauta a un sospechoso de terrorismo su equipo, dentro de éste se encuentran ficheros
que se podrían considerar de vital importancia para continuar con la investigación, pero
muchos de esos ficheros están cifrados y se sabe que mediante PGP simétrico.
Gracias a la investigación del sospechoso tus compañeros te han dado las siguientes
pautas que sigue el sospechoso a la hora de crear sus contraseñas:
Son de longitud de 6 a 7 caracteres.
Sólo contienen letras minúsculas
Sólo se utilizan estas letras: eghotu
No se repite ninguna de las letras de la contraseña
Algunas de ellas contienen dos números entre estos: 0134
Tu trabajo será intentar descifrar el fichero gracias a la investigación realizada sobre
el sospechoso y a los datos proporcionados para determinar si el contenido es de vital
importancia para la investigación en curso.
Este es un ejercicio bastante sencillo y directo, ya que la descripción proporciona las reglas para crear el diccionario correcto. Por extraño que parezca, estos son los tipos de retos que más me cuestan :(
A pesar de ello, gracias al modo de máscara de JTR, por fin he sido capaz de pasar la primera parte de este reto (dos meses después del tiempo límite, me da que ya es un poco tarde) en una hora o dos, con esta orden tan sencillita:
john -mask=[eghotu0134] -min-len=6 -max-len=7 medium_11.gpg_HASH --format=gpg-opencl
La explicación de los parámetros:
-
-mask
le dice a JTR que use el modo de máscara, usandoeghotu0134
como alfabeto. Aunque no sigue exactamente las guías, en concreto lo de no se repiten las letras y contiene dos números, creo que es más sencillo ir por todas las combinaciones en vez de andar puliendo el diccionario. Obviamente, alguien con más conocimiento del uso de las reglas en JTR podrá llegar mucho más rápido a la solución. -
-min-len
y-max-len
están ahí por las guías que dicen que la longitud de la contraseña es de 6 ó 7 caracteres. -
medium_11.gpg_HASH
es el hash sacado porgpg2john
, otra de esas herramientas increíblemente útiles para convertir cualquier formato en algo que JTR entienda. -
Finalmente,
--format
está ahí para decirle a JTR que usa la GPU, en lugar de la CPU (que es mucho más lenta).
Después de una hora y media, JTR saca la contraseña: eg1u03
. Es interesante el hecho de
que hay tres números ahí, mientras que en las guías nos decían que podría haber dos
números. Me lo tomaré como una lección de que esas guías no son siempre 100% correctas.
Si no puedes sacar la contraseña y tienes la seguridad de que el diccionario está bien
hecho, intenta expandir la búsqueda a otros casos que no sigan todas las reglas, sólo
algunas (por ejemplo, permitir varios números en vez de sólo dos).
En fin, los datos cifrados son la siguiente imagen:
Quizá algunas personas hayáis identificado los símbolos que aparecen en la imagen con el cifrado Pigpen. Los símbolos de la parte de arriba de la imagen y la de abajo son los mismos; y, descifrados, dan el siguiente texto plano (con los espacios añadidos por mí):
ERES MUY GOLOSO
Así que la flag es (o al menos eso creo, porque no pude completar este reto a tiempo)
ERESMUYGOLOSO