Needle in a haystack

Текст задания:

https://www.youtube.com/watch?v=sTKP2btHSBQ

Да, всё верно, нам дана ссылка на youtube и всё. Ок, переходим по ссылке и видим девятичасовое видео… В котором нам надо как-то найти флаг…

SECCON
Ладно, скачиваем его (720p — ~8гб; 360р — ~2гб) — я качал 360р.
После нескольких минут просмотра появляется идея. На видео постоянно мигают различные источники света, а что если какой-то из них передает азбуку Морзе? Да ну, бред какой-то…
Перематываем видео ближе к рассвету и замечаем, что в большей части окон свет погас, кроме одного… Мотаем еще дальше и свет гаснет… И снова включается. Оно? Перематываем на утро и видим, что это же самое окно то закрывается, то открывается! Бинго!

2scr 3scr 4scr 5scr

Разбиваем загруженное видео на кадры (1 кадр каждую минуту):

ffmpeg -i videoplayback.mp4 -vf fps=1/60 frames/img%08d.jpg

Кропаем нужную нам часть изображения:

mogrify -crop 26×14+561+285 frames/*.jpg

7scr

Анализируем. Понимаем, что тёмное окно в течении 1 минуты (= одному изображению) — это пауза между сигналами, тёмное окно в течении 3 минут (= трём изображениям) — пауза между буквами, 1 минута светлого (или открытого в дневное время) окна — это точка и 3 минуты светлого (открытого) окна — это тире.
Можно перевести вручную, а можно написать кривой небольшой скрипт:

import os
from PIL import Image

im = Image.open('frames/img00000002.jpg')
pix = im.load()
signal_r_min = pix[4,3][0] - 20
signal_r_max = pix[4,3][0] + 20

res = ""
files = os.listdir('frames')
files.sort()
for name in files:
    im = Image.open('frames/' + name)
    pix = im.load()
    try:
        if (pix[4,3][0] > signal_r_min) and (pix[4,3][0] < signal_r_max):
            res += "1"
        else:
            res += "0"
    except:
        print("except")
res = res.replace('000', ' ').replace('111', '-').replace('1', '.').replace('0', '')
print(res)

Что даст нам
... . -.-. -.-. --- -. -.--. ... --- -- . - .. -- . ... -....- .- -....- ... . -.-. .-. . - -....- -- . ... ... .- --. . -...- -... .-. --- .- -.. -...
А именно seccon?sometimes?a?secret?message?broadb?
Упс, видимо скрипт доходит до определенного момента (например рассвет) где значения пикселя выбивается из диапазона signal_r_min/signal_r_max.
Меняем files.sort() на files.sort(reverse=True), не забываем реверснуть полученный набор символов, декодируем и получаем s?boldly?
Дальше забиваем и вручную получаем оставшуюся часть флага 🙂
Флаг: SECCON(SOMETIMES-A-SECRET-MESSAGE-BROADCASTS-BOLDLY)


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *