この記事は Harekaze Advent Calendar 2017 の15日目の記事です。
チームHarekazeでは、2018年2月10日にHarekaze CTF 2018を開催します。
ksnctf C92 WriteUp
最近全然CTF系のことをできていないのですが、Advent Calendarに何を書くか考えていて、夏に隣の席の人からある本を手に入れたことを思い出しました。
ksnctf C92 です。
ksnctfのコミケC92向けスピンオフだそうです。
上記の写真の本はコミケ当日に頒布された解説本です。
コンテスト自体については早めにサインアップしたもののその後放置という感じでした。
今回は夏に買ったこの解説本を読みながら、冬になった今ちょっとだけ自分でやってみたよーという内容です。
E1 - Mysterious Light
表
flag.png
ファイルに謎の光に隠されたQRコードが載っています。
QRコードのカドの位置検出パターンを塗るとQRコードが完成し、QRコードリーダーで読むことができるようになります。
FLAG{QyDYkTQNd1lb1IDH}
裏
flag2.png
に巨大なQRコードが載っていて、コードの大部分は隠されていませんが、ほんの少しだけ謎の光で隠されています。
この状態ではQRコードリーダーで読めません。隅の位置検出パターンを見つけているような気配はありますが、一向に読み取りは進みません。
位置検出パターンの周囲には以下の2つの形式情報が載っています。
- QRコードの白黒がまんべんなく散らばるようにかけるマスクとして8種類のうちどのマスクを使用したか
- 4種類の誤り訂正レベル
この2つが欠けると読み取りを進めることができません。
形式情報は3つの隅に分散・多重化して記述されていますが、謎の光はちょうど形式情報が配置されているところを隠してしまっています。
マスクと誤り訂正レベルの組み合わせはそんなに多くないので総当りができます。
その2つをオプションとして渡せる強力なQRコードデコーダーがstrong-qr-decoderです。
QRコードのデータは明暗を表す記号(と不明を表す?
)で記述したファイルで渡す必要があります。
画像から記号表記に直すコードはこんな感じ。
XXXXXXX_??_XX__XX_XXX__X___XX__XX__X_XX_X__X_XXXXXX_XX_X__X_X__XXX_X_XX__X_X_____XXX______XX______XXXXX__XX__XXXX_X_X__XXXX___XX__XXX____XXX_X_XX__X_XXX___X_X__X___X_X___XXXXXXX X_____X_??XXXX__XXXXXX_X___XX_XX_XXXX__X_X_X__X_____X__X_XXX___XXXX_____X____X_XXXXXXX_X_X___XX_X_X___XXX__X_XXXXX_XX_____X________XXXX__XX__XXXX__X_XXXX_XX_X_X_X_XX_X_X_X_____X X_XXX_X_??___XXXXX_X__X_X_XXX__XX_XX_XXX_XXX_X__X__X____X____XXXXXX_X__X___XXX_XX__X_X_X___XXX__XX__XXX__XXX______X_XXX__XX_XX__X___X__X_X_X____X___XX____X____X_X__XXX___X_XXX_X X_XXX_X_??XX_X____X_________X_XX___XXX_X_X_XXX____X_XX_X_X__X____X__XX_XX_X_XX_X__X__X_X_XXXXXXX_XXX__X_XX__X_XXXXX_X____X___XXXX__X_X__XXX____XXX_XXX__X_XX_X____XX___XX_X_XXX_X X_XXX_X_??XXXXXXX_XX_XXXX__XXXXXX_XXX_XXXXXX_X____X___XXXXXXX_X___X_XX__X______XX_XXXXXXX___XX_X____X__XX_X_X_X_XXXXX_X__X_X_XXXX_XX___X_XXXXXXXX_X_X___X___X____XX_______X_XXX_X X_____X_??XX_XXXX_X_XXXXX___X___XX__X__XX_X__XXX_X__XXXXX___X___XX_X__XX__X_XX__XX_XX___X___X___XX_XX_XX_XX___XXX___XXXX_XXX_X_X_XX_XXX___XXX___XX_XX__________XX_____X_X_X_____X XXXXXXX_??X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_X_XXXXXXX _______???_X_XXXXXXX_XX_XX__X___X___X_XX____X_XXX_X__X__X___X_X__XXXXXXXXXX______X__X___X__X___XX__X__XX___X___XX___X__X__X__X_XX_XXX__X_X_XX___X_XXX____X_XXXXX_____X___________ ??????????X___XXX_XX____X___XXXXXX___XXXXX_X_X_____X_X_XXXXXX_XXXX_X___XX_XXX_______XXXXXXXXX_XX_XX_X_X__XXXXXX_XXXXXXX_X____X_X_XX____X___XXXXXX_XXXXX______XXXXXX__X_XX???????? ??????????__X_XXXX_______XX__XX__XX_XXXX__X_____XXXXXXXXX__X_____X_X__XX__XX___________X____XXXX____XXX_XX__XXXX_X_XX__XX_X___XX_X_XX__X_X_____XX__XXXX__XXXX__XX_XXX__XX???????? XX____XXXX____XXX_XXX_X_X__X__X__X_XX_X_XX_X__X__X_X___XX__XX____X_X_XX_X_______XXXX_____XX_XXXX___XX_XXX__XX_XX__XXXX_X__XXX____X__X__X_X_XX__XXXXX_XXXXX___XXX__XXX_X_X_____X_X XX_X_X____X__XX__XXX___X_X_X__XX__XXXX_XXX____X_X_XX_X_____X_____X_X_XXXX_X_XX____X_X____X_X_X____XX_X___X_X_X_X__XX___X___XX___XXX_XXXXXX____XXX___XX_XXXX____X_X_X_XX__X_X_X__X _XXX__XX_____XX_XXXX_XX___XX_X______XX_X_X_X___X_XXXXXX_X___XXXXX__X_X_X_XXX_X_XX__XX__X__X_XXXXXX__X__X_X_X_XXXXX_X___X_X__XXX_X__X_X_XXXX___X_X__XXXXX___XXXX_X___XX____XX___X_ _X__X__X_____X_XX__X_XXXX_X______X___XXXX_XXXXXXX__X_XXXXXXXX__XXXXXX_X_XXX__XXXX_XX___XXX__X_XX_X_X__X_XXX__XXXXX__X__X_X_X_X_XX______X___XXX____X_____XX_X___XXX_X_XX_XXX__XXX_ いかりゃく
これをstrong-qr-decoderに、パラメータを変えて投げます。
$ for ((i = 0; i < 8; i++)) do for ((j = 0; j < 4; j++)) do python2 sqrd.py -e $i -m $j flag2.txt done done error: 未対応のモード指示子です error: 未対応のモード指示子です Traceback (most recent call last): File "sqrd.py", line 1056, in <module> data.extend([ord(alphanumeric_table[num // 45]), ord(alphanumeric_table[num % 45])]) IndexError: list index out of range Traceback (most recent call last): File "sqrd.py", line 1072, in <module> data.append(int(data_bits[:8], 2)) ValueError: invalid literal for int() with base 2: '' error: 未対応のモード指示子です error: 未対応のモード指示子です Traceback (most recent call last): File "sqrd.py", line 1056, in <module> data.extend([ord(alphanumeric_table[num // 45]), ord(alphanumeric_table[num % 45])]) IndexError: list index out of range error: 誤り訂正に失敗しました。--no-correctionオプションの仕様を検討してください error: 誤り訂正に失敗しました。--no-correctionオプションの仕様を検討してください error: 未対応のモード指示子です Traceback (most recent call last): File "sqrd.py", line 1056, in <module> data.extend([ord(alphanumeric_table[num // 45]), ord(alphanumeric_table[num % 45])]) IndexError: list index out of range FLAG{sttzFKrw6NY1VCd6zZrUL7f7bmba86f7B3f63XbZDAacbNfopNJpuyAsu0rHZ9KIrIBtYe0jg9jg4ke2rXg2dDWsoreTpTR31tSbFBVtxnzVIWyQIjfRQNswaYwG1tnM06MmtweK4fxMCrIKjB7Id5Zo7g4Xe0VFJtXpS5LoIFifp7Zby3j2a4LAnaK3buZBc95WcaAzERfGX1aba70cYYA2WCVS36w5rFDYtC8YVqGfAbrM6nO5bU4AFupjmB5WOiToscqK38a3KQHNvNvN4I8YePjeEbxPBBHO3g141EqskqODlOvoL7ZvWxwACyEJE62iaW18JTXd8ZvPupcVX1fc2pSyY68vTarClvEFX2WV3GMmK8rZUnhCWjfEuqxdfWnteD9FxzDedqwn3bvTUP8Mf2oGM0fxsa8R56n5jVP6o45U1tLTaWGjHiSHg4NEC1y1aLLvqgdCfHJTUY2aRcfFUauR5NiJMYkqiKNe7h3FWt9PYEJTYeV8v93Iarv8sKLvELrVnxjbLB6QKoIYrSYgox71DLRw5Pipah68GPkKYjUKnYESxSfhtqI72hRZ3sIbi2O3g8W7jfK900lZVKXQG3vqpRgynKcMQvIvOaryfwfiTq26g7SnuEvRpNxZbx0OOk3uws1tnYuKU9NyYnVI7RHU5tIPkFFvCFRI9ggBIAXDeIGa93vmQu01VoaKslimfE3e85A94F8EGmu7iQtVntUdq7EdAX7wJiZ3Z26aBjZxrLOQiCh5WL6mcDfIB8W9z5tCCf1aKbRrchTXMeN24bmextbzcp1MVs4gX9XTziS7oKxorCHSy7pNZsj39z4Y96lCkBFErtPxlSN9s5s9ZNVJK1LASOowu3Sea6IXA2SJsbqLT6j7tbVwpIb7TuhrXzL6gLdquh57TgCX3ZBBQrFTCAUUu0xDakU7DTWOI2Rm2YoKxo4IFKQhin546VjG6MKLJsBWi7fvhnUNtrQM5fChIALMovG7uQMqhFbRSdUcRSayBzKQTjZP9sZGXc0ZiaXCo5OQMbJoKglrdJshqYepRfjVpvXtLfvqOIuj85mKHJz2Yn3v1fcYO7hJ3k4phDDDyPVHcb4ZtcxfhEjH3XuSCcG2kfy1WMFRvnmbjGr6K7In3JTULqQxpxCuM4aFJy2AlS23jclhFbhGkCDMVHu0CGzmnOM56IouIsC29LTqdsAj5W1ts8zbBiIDNCNW8xxXUSAZN52tUc2jXK29sxZaz65HDLjGlphb5wavmq6t4Ez} error: 未対応のモード指示子です いかりゃく
FLAG{sttzFKrw6NY1VCd6zZrUL7f7bmba86f7B3f63XbZDAacbNfopNJpuyAsu0rHZ9KIrIBtYe0jg9jg4ke2rXg2dDWsoreTpTR31tSbFBVtxnzVIWyQIjfRQNswaYwG1tnM06MmtweK4fxMCrIKjB7Id5Zo7g4Xe0VFJtXpS5LoIFifp7Zby3j2a4LAnaK3buZBc95WcaAzERfGX1aba70cYYA2WCVS36w5rFDYtC8YVqGfAbrM6nO5bU4AFupjmB5WOiToscqK38a3KQHNvNvN4I8YePjeEbxPBBHO3g141EqskqODlOvoL7ZvWxwACyEJE62iaW18JTXd8ZvPupcVX1fc2pSyY68vTarClvEFX2WV3GMmK8rZUnhCWjfEuqxdfWnteD9FxzDedqwn3bvTUP8Mf2oGM0fxsa8R56n5jVP6o45U1tLTaWGjHiSHg4NEC1y1aLLvqgdCfHJTUY2aRcfFUauR5NiJMYkqiKNe7h3FWt9PYEJTYeV8v93Iarv8sKLvELrVnxjbLB6QKoIYrSYgox71DLRw5Pipah68GPkKYjUKnYESxSfhtqI72hRZ3sIbi2O3g8W7jfK900lZVKXQG3vqpRgynKcMQvIvOaryfwfiTq26g7SnuEvRpNxZbx0OOk3uws1tnYuKU9NyYnVI7RHU5tIPkFFvCFRI9ggBIAXDeIGa93vmQu01VoaKslimfE3e85A94F8EGmu7iQtVntUdq7EdAX7wJiZ3Z26aBjZxrLOQiCh5WL6mcDfIB8W9z5tCCf1aKbRrchTXMeN24bmextbzcp1MVs4gX9XTziS7oKxorCHSy7pNZsj39z4Y96lCkBFErtPxlSN9s5s9ZNVJK1LASOowu3Sea6IXA2SJsbqLT6j7tbVwpIb7TuhrXzL6gLdquh57TgCX3ZBBQrFTCAUUu0xDakU7DTWOI2Rm2YoKxo4IFKQhin546VjG6MKLJsBWi7fvhnUNtrQM5fChIALMovG7uQMqhFbRSdUcRSayBzKQTjZP9sZGXc0ZiaXCo5OQMbJoKglrdJshqYepRfjVpvXtLfvqOIuj85mKHJz2Yn3v1fcYO7hJ3k4phDDDyPVHcb4ZtcxfhEjH3XuSCcG2kfy1WMFRvnmbjGr6K7In3JTULqQxpxCuM4aFJy2AlS23jclhFbhGkCDMVHu0CGzmnOM56IouIsC29LTqdsAj5W1ts8zbBiIDNCNW8xxXUSAZN52tUc2jXK29sxZaz65HDLjGlphb5wavmq6t4Ez}
E5 - Not Guilty?
pcapファイルなのでWireSharkで開きます。
プロトコルの列を見ると802.11と書いてあります。Wi-Fiですね。
photo.jpg
によるとWPA2らしいのでまぁ暗号化してあるんだな―という感じです。
WPA2のパスワードはphoto.jpg
内のカードに書いてあり、WireSharkではパスワードを使って復号ができるそうです。便利。
Edit/Preferences/Protocols/IEEE802
Enable Decription
にチェックを入れ、DecryptionKeysのEditからWPAのパスワード認証でパスワードを設定します。
そうすると暗号化で真っ白だったストリームが複合されてHTTPの混ざったTCPストリームになりました。
WireSharkは便利なものでHTTPストリームの中に含まれるコンテンツをエクスポートできるそうです。
File/Export Objects/HTTP
flag.jpg
が見つかりました。
FLAG{bBVqBLqTxy3pR4F8}
E6 - flower
1
StegSolveでポチポチします。
Blue plane 1
で発見。
FLAG{ZPf1dTqXQcbD0ygl}
2
1問めで見つけたヒントに従って解きます。
IDAT
はpngのチャンクのうち、画像本体を含むチャンクだそうです。
チャンク毎の表示、編集にはTweakPNGが便利とのことで見てみました。
最後のIDATだけやけに大きく、それまでのIDATのlengthは最大49~125くらい・・・
$ ipython Python 3.6.1 (default, Mar 24 2017, 12:50:34) Type 'copyright', 'credits' or 'license' for more information IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: ''.join([chr(i) for i in [70,76,65,71,123,49,106,109,109,90,83,76,52,65,55,70,83,86,121,66,122,125]]) Out[1]: 'FLAG{1jmmZSL4A7FSVyBz}'
FLAG{1jmmZSL4A7FSVyBz}
3
Hint2は
下を見ろと言っています。
TweakPNGはpngのデータ編集もできるのでIHDRチャンクからEditで
べんり。
FLAG{ozwPlyihMxgnxey0}
所感
色々やってみるより前に本を手に入れた(そして放置していた)ので、ネタバレというか先に読んでから解いてしまった問題が多かったです。反省。 あとだいたいSteganographyとか画像っぽいのとかpcapとかMiscばっかり見てしまうのでそろそろ他のもちゃんと勉強したいなとは思いました。やるとは言っていません。
2018年2月10日にHarekaze CTF 2018が開催されます。
2018年2月10日土曜日15時(JST)からHarekaze CTF 2018を開催します。
— Harekaze (@TeamHarekaze) 2017年12月11日
(競技時間:24時間)
今、登録ページを準備中です。
Harekaze CTF 2018のURLは次の通りです。https://t.co/MOPwRLFROVhttps://t.co/gRIciPOaJoのリンクはこちら。https://t.co/XZ2MrQufzw #HarekazeCTF
せっかくメンバーに入れてもらっているので雑用を色々お手伝いしてます。
作問もする予定・・・
ネタというか方向性だけは一案あるんですがまだ全然考えてません。がんばります。
僕以外のみなさんは作問たくさんしててすごーいな感じです。勉強します。
しんちょく pic.twitter.com/biKoLB9FHc
— yue82@る (@yue_roo) December 13, 2017