helloworlds

not a noun, it's a verb

【CTF】Pythonで暗号を解く?!

過去に中古で購入したとある本で見かけたCTFという、 コンピュータ分野におけるセキュリティ分野における競技があること知った。

その中からおもしろい問題を見つけたので、 今回はそちらを取り上げてみる。

使用する言語は、Python

なかなか問題のファイルを見つけ出すのに苦労した... 5年前くらいの問題みたいなので...

ただ、知っておくとおもしろいと思うところがありました。

今回使用するファイルですが、ブログ内では紹介しません。 もし知りたい方がいましたらコメントなどで教えてください! (※ ただし元が信用できるダウンロード先ではないかもしれないということを覚えておいてください。)

いざ、やってみる

まず、問題で使用するファイルをダウンロード。

そのファイルをfileコマンドで形式を調査する。

$ file sample01
sample01: PNG image data, 19025 x 1, 8-bit/color RGBA, non-interlaced

するとファイルは画像ファイル?っぽいかんじ。PNGだな〜。

一旦macのFinderでファイルをダブルクリックしプレビューで表示してみた。

f:id:o21o21:20180527140511p:plain

「ん? なんもうつってないのか?」

もうお気づきの方はいると思いますが、この画像ファイルは先ほどコマンドかけたときに出力されている通り、 サイズが19025 x 1の画像ファイルだ。

だから真っ暗。 試しに拡大してみる。

f:id:o21o21:20180527140754p:plain

「おお!なんか1ドットで幅が長いなんかでてきた!」

よく見てみるとある規則に基づいて黒い線と青い線が入っている。

「これはまさに暗号じゃねえか」と少しテンションがアガるwww

ここからはもう知っているか知らないかの問題になってくる。

こうした画像データを扱うのにはPythonがいいのでは?

 #!/usr/bin/python
  
from PIL import Image
 
y = 25
orig_img = Image.open('sample01')
img  = Image.new('RGB', ((19025/y, y+1)))
img.putdata(orig_img.getdata())
img.save("new_sample01.jpg")

7行目、オブジェクト,imgを新たに作成。 RGB形式で縦y, 横19025/yドットとする。 この25を変えれば縦幅の違う画像ファイルを生成できる。

さて実行。 

$ python sample01.py 

「おぉぉぉ!」

f:id:o21o21:20180527144139p:plain

「アイ ラブ ミー??」

なんか変だな。数字意味不明だ。

数値を変更する。

f:id:o21o21:20180527144439p:plain

右側に青い線が斜めにはしっているのがわかる。 この青い線を真っ直ぐにしてあげる必要がある。

#!/usr/bin/python

from PIL import Image

x = 450
y = 10025

orig_img = Image.open('sample01')
img  = Image.new('RGB',((x, (19025/x)+1)) )

for i in range(y):
    print orig_img.getpixel((i,0))
    i += 1

img.putdata(orig_img.getdata())
img.save("new_new_sample01.jpg")

さあ...

f:id:o21o21:20180527150001p:plain

「おお〜 バッチリ」

出力された以下の部分が青い線のところっぽい。

(16, 156, 239, 19) (16, 156, 239, 255)

コードの作成や参考記事を見たりしましたが、けっこう理解に時間がかかりました。 ただ、こういうこともできるとか1度でも実際に自分でやってみると、 今後に役立ちそうなかんじです。