PL: Misja Gynvaela PL011
Zadanie⌗
Na 49 streamie nie pojawił się co prawda utęskniony raytracing “bardzo rozproszony”, ale próba kryptoanalizy szyfrogramu na żywo również okazała się tematem wartym uwagi. Jak zwykle, pod koniec streamu czekała na agenta (lub nas) misja. Jej treść brzmi następująco:
MISJA 011 goo.gl/keE94T DIFFICULTY: █████░░░░░ [5/10]
┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅
Jednemu z naszych agentów polowych poszczęściło się - zakradł się do biura
podejrzanego i zrobił zdjęcie bardzo ważnego dokumentu. Zdjęcie udało się wywołać
i otrzymaliśmy dzisiaj archiwum z jego skanem.
Ponieważ jestem obecnie bardzo zajęty i mam bardzo ważne spotkanie, poniżej jest
link do pliku - zajmij się tym.
goo.gl/A6sMwA
Powodzenia!
--
Odzyskaną wiadomość umieść w komentarzu pod tym video :)
Linki do kodu/wpisów na blogu/etc z opisem rozwiązania są również mile widziane!
P.S. Rozwiązanie zadania przedstawię na jednym z vlogów w okolicy dwóch tygodni.
Zaczynamy!⌗
Pod linkiem znajdującym się w misji, umieszczony został plik o rozszerzeniu bin. Polecenie file
albo szybkie spojrzenie w hexedytor rozjaśnia sytuację - to archiwum 7z (jeśli Czytelnik spodziewał się radare2 w tym wątku - tak ono również rozumie tego magica ;] ).
λ file 43842e832bfe28328309053ce1b1a49afc1047e5.bin 43842e832bfe28328309053ce1b1a49afc1047e5.bin: 7-zip archive data, version 0.4
Wypakowanie zawartości zajmuje chwilę. Wewnątrz mamy 76 801 plików. Hm, no ciekawie. Okazuje się, że te pliki to PCX skompresowane RLE (hm, my się chyba znamy z innej misji). Żeby tego było mało wszystkie są jednakowej wielkości.
λ file ffff609e5415
ffff609e5415: PCX ver. 3.0 image data bounding box [0, 0] - [319, 239], 3 planes each of 8-bit colour, RLE compressed
Przeczesałem główne archiwum jak i kilka pojedynczych randomowo wybranych plików. Niestety exiftools
nie potrafiły znaleźć ukrytej treści. Czyli chyba trzeba rozwiązać to “the hard way” łącząc te obrazki. W związku z tym, że każdy był rozmiaru 320x240 i nieparzystej liczby to odrzuciłem od razu możliwość rozbicia dużego obrazu na pojedyncze i mniejsze. Zacząłem więc nakładać na siebie obrazki.
Pierwszy fail⌗
Piniższy kod prezentuje moją próbę połączenia PCXów w jeden obrazek. Oczywiście strukturę pliku musiałem potem odtworzyć.
import os
prefix = "./wyj/"
def main():
fs = []
for file in os.listdir(prefix):
with open(prefix + file, 'rb') as f:
fs.append(list(f.read()))
print("xoring now")
bstr = fs[0]
for f in fs[1:]:
for i in range(0, k):
bstr[i] += f[i]
with open("dump.bmp", 'wb') as f:
f.write(bytes(bstr))
if __name__ == '__main__':
main()
Niestety nie wiedziałem, że plik PCX nie obsługuje kanału ALFA czyli przeźroczytości. Dlatego po otrzymaniu wynikowego obrazka zobaczyłem wielki, ciekawy… czarny ekran. Tak wyglądało to w hexedytorze:
A tak po wczytaniu pliku raw (.data) przez GIMPa.
Rozwiązanie⌗
Postanowiłem zmienić podejście i skonwertować PCX na BMP a następnie powtórzyć operację. Konwersji dokonałem za pomocą polecenia:
mogrify -path "path/here" -format bmp *
Mogrify uporał się z całą gromadką plików w niewiele ponad 5 minut. Zmodyfikowałem trochę skrypt. Stworzyłem obraz 400x400 (nie sprawdzałem pojedynczo plików, to był taki failsafe na wypadek wyjścia poza te 320x240) i zacząłem nakładać pixele. Kod wygląda tak:
from PIL import Image
import os
import numpy as np
import time
import progressbar
import operator
prefix = "./tmp/"
def main():
fs = []
out = Image.new("RGB",(400, 400))
pxs = out.load()
out.save("output.bmp")
bar = progressbar.ProgressBar()
for file in bar(os.listdir(prefix)):
im = Image.open(prefix + file )
row, col = im.size
f = Image.open('output.bmp')
pxs = f.load()
for r in range(row):
for c in range(col):
pxs[r,c] = tuple(map(operator.add, pxs[r,c], im.getpixel((r,c))))
f.save("output.bmp")
print('END')
if __name__ == '__main__':
main()
Z każdym kolejnym krokiem obrazek wyglądał coraz lepiej:
Tutaj pasek postępu i “ETA”:
Rozwiązanie coraz bliżej:
No i obrazek w całości:
Śliczny widok ;) a dzisiejszą flagą jest:
Pocztówka z wakacji
Kudos dla KrzaQ, który wyprzedził mnie w swoim rozwiązaniu. Jego post znajdziecie tutaj
Dzięki za misję Gyn!