Datos del reto
| Campo | Valor |
|---|---|
| CTF | Taipanbyte CTF |
| Reto | Indian WAV |
| Categoría | Esteganografía |
| Flag | TB{H1dd3n_W@ve_Fl@g} |
Descripción del reto
El archivo wav.tb es un WAV real (RIFF, PCM 24-bit estéreo, 44100 Hz). El mensaje está oculto con esteganografía LSB en los bytes de audio, usando orden de bits big-endian al reconstruir cada byte.
Reconocimiento
- Confirmar formato:
file wav.tb→ RIFF WAVE, PCM 24-bit estéreo. No hay datos extra después del chunkdata. - Hipótesis LSB: En el hex dump se ve un patrón repetitivo al final (
01 01 00 00 01 00...), típico de LSB en las muestras.
Análisis de la vulnerabilidad
- Se toma el bit menos significativo (LSB) de cada byte del bloque de audio (a partir del byte 44, tras la cabecera).
- Se agrupan los bits de 8 en 8 para formar bytes.
- Orden de bits: Hay que probar ambas convenciones al empaquetar 8 bits en un byte:
- Little-endian: primer bit → bit 0, último → bit 7.
- Big-endian: primer bit → bit 7, último → bit 0.
Con big-endian los primeros bytes ya son ASCII y se lee la flag al inicio del mensaje.
Explotación
Extracción LSB con orden MSB first (big-endian). Los primeros bytes extraídos son:
TB{H1dd3n_W@ve_Fl@g}#############################################...
El resto son caracteres de relleno (# o similar).
Script mínimo (Python)
with open('wav.tb', 'rb') as f:
data = f.read()
audio = data[44:] # después de cabecera WAV
bits = [b & 1 for b in audio]
# Empaquetar 8 bits en 1 byte, MSB first (big-endian)
msg = bytes(sum(bits[i+j] << (7-j) for j in range(8)) for i in range(0, len(bits), 8) if i+8 <= len(bits))
print(msg[:60].decode()) # TB{H1dd3n_W@ve_Fl@g}...
Flag
TB{H1dd3n_W@ve_Fl@g}
Lecciones aprendidas
- Técnica: LSB (1 bit por byte de audio).
- Alcance: todos los bytes del bloque
data(no solo un canal). - Detalle importante: el orden de bits al formar cada byte es big-endian (primer bit = MSB). Con little-endian no sale texto legible.