Tags: spectrogram fft 

Rating:

# Aero CTF 2020 - Image Wave (Code, 498pts)

Why didn't many peaple solved this? It's just an implementation of IFFT from spectrogram.

## Challenge Details

We are given three image files.

![](https://i.imgur.com/MaTxT07.jpg)

![](https://i.imgur.com/2wgQjy3.jpg)

![](https://i.imgur.com/AeQRDHm.png)

Obviously the first two is [spectrogram](https://en.wikipedia.org/wiki/Spectrogram), which should simply be a result of FFT of the signal. And as the third image suggests, we should implement inverse of FFT (IFFT) to recover the original data.

I implemented a solver with Node.js.

```javascript=
const {promises: fs} = require('fs');
const color = require('color');
const {ifft} = require('fft-js');
const {WaveFile} = require('wavefile');
const jimp = require('jimp');

(async () => {
const wav = new WaveFile();

const lennaA = await jimp.read('imga.png');
const lennaP = await jimp.read('imgp.png');

const signals = []

for (const x of Array(3941).keys()) {
if (x % 100 === 0) {
console.log('progress:', x);
}

const phasors = [];
for (const y of Array(1024).keys()) {
const hueA = color(lennaA.getPixelColor(x, 1080 - y) >> 8).hue();
const hueP = color(lennaP.getPixelColor(x, 1080 - y) >> 8).hue();

const valueA = (300 - hueA) / 300 * 12 - 6;
const valueP = (300 - hueP) / 300 * 12 - 6;
phasors.push([valueA ** 9, valueP ** 9]);
}

const signal = ifft(phasors);
signals.push(...signal);
}

wav.fromScratch(1, 22050, 32, signals.map((v) => v[0] * (2 ** 17)));
await fs.writeFile('out.wav', wav.toBuffer());
})();
```

This produces the following output:

<audio controls src="https://hakata-public.s3-ap-northeast-1.amazonaws.com/aeroctf/out.mp3"></audio>

We can hear the synthesized voice of some digits starting from 1:29. Transcribe it and get flag:

`Aero{44130800454087113922111421638436416130198703185043619684674310673384316}`

Original writeup (https://hackmd.io/@hakatashi/ryHAY-9NU).