この記事は、TSG Advent Calendar 2016 - AdventarとIS17er Advent Calendar 2016 - AdventarとCTF Advent Calendar 2016 - Adventarの5日目の記事として書かれました。
駒場祭でTSGの展示の一環として、TSGCTF(オフラインのセキュリティコンテスト的なもの)を開催しました。
問題やスコアサーバともに部員の手作りで、問題は基本的に毎週金曜に開催しているCTF分科会で出されたものをまとめて出しました。
会場の様子はこんな感じ。(TSGが開発しているゲームMNEMO プログラミング風パズルゲームをプレイしているひとが多いので、全員がCTFやっているわけではありません。)
私が作った問題のwriteupを書いていこうと思います。
SQL[PPC?]
問題<stage1> count 1 to 100 in sqlite3! (length limit 80 words) insert nor creat query is prohibited. <Stage2> Output sequence below in ONE line. 2,3,7,23,59,314,1529,8209,83313,620297,7869898,126742987,1687054711,47301104551,1123424582771,32606721084786.0,1.66231521597106e+15,6.19580465542266e+16,4.25799888444834e+18,3.34806306946199e+20,2.33857567318697e+22,3.4163728687278e+24,3.97068399296019e+26,6.25954414096408e+28,1.58862800856536e+31,2.99327078237057e+33,1.10746410850255e+36,4.24202695773047e+38,1.57131202095317e+41 (length limit 140) <stage3> Output this! #............................................................... ##.............................................................. #.#............................................................. ####............................................................ #...#........................................................... ##..##.......................................................... #.#.#.#......................................................... ########........................................................ #.......#....................................................... ##......##...................................................... #.#.....#.#..................................................... ####....####.................................................... #...#...#...#................................................... ##..##..##..##.................................................. #.#.#.#.#.#.#.#................................................. ################................................................ #...............#............................................... ##..............##.............................................. #.#.............#.#............................................. ####............####............................................ #...#...........#...#........................................... ##..##..........##..##.......................................... #.#.#.#.........#.#.#.#......................................... ########........########........................................ #.......#.......#.......#....................................... ##......##......##......##...................................... #.#.....#.#.....#.#.....#.#..................................... ####....####....####....####.................................... #...#...#...#...#...#...#...#................................... ##..##..##..##..##..##..##..##.................................. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#................................. ################################................................ #...............................#............................... ##..............................##.............................. #.#.............................#.#............................. ####............................####............................ #...#...........................#...#........................... ##..##..........................##..##.......................... #.#.#.#.........................#.#.#.#......................... ########........................########........................ #.......#.......................#.......#....................... ##......##......................##......##...................... #.#.....#.#.....................#.#.....#.#..................... ####....####....................####....####.................... #...#...#...#...................#...#...#...#................... ##..##..##..##..................##..##..##..##.................. #.#.#.#.#.#.#.#.................#.#.#.#.#.#.#.#................. ################................################................ #...............#...............#...............#............... ##..............##..............##..............##.............. #.#.............#.#.............#.#.............#.#............. ####............####............####............####............ #...#...........#...#...........#...#...........#...#........... ##..##..........##..##..........##..##..........##..##.......... #.#.#.#.........#.#.#.#.........#.#.#.#.........#.#.#.#......... ########........########........########........########........ #.......#.......#.......#.......#.......#.......#.......#....... ##......##......##......##......##......##......##......##...... #.#.....#.#.....#.#.....#.#.....#.#.....#.#.....#.#.....#.#..... ####....####....####....####....####....####....####....####.... #...#...#...#...#...#...#...#...#...#...#...#...#...#...#...#... ##..##..##..##..##..##..##..##..##..##..##..##..##..##..##..##.. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. ################################################################
stage1からstage3まであります。
sqlite3で再帰をしようという問題です。sqlite3.8.3以降にはWITH句という再帰ができる構文があり、これを使うことを想定しています。この問題は、結局部員にしか解いてもらえませんでした…。
sqlite3 withと検索すると公式ページSQLite Query Language: WITH clauseが出てくるので、これを読みながらやります。
stage1の解答は、普通にやると
with recursive c(x) as (select 1 union select x+1 from c limit 100) select x from c;
となってしまい、これでは80文字以内に収まりません。
しかし、公式ページの一番下に
The SQL:1999 spec requires that the RECURSIVE keyword follow WITH in any WITH clause that includes a recursive common table expression. However, for compatibility with SqlServer and Oracle, SQLite does not enforce this rule.
と書いてあるので、実はrecursiveはいらないことが分かります。
よって、解答は
with c(x) as (select 1 union select x+1 from c limit 100) select x from c;
stage2は数列を検索するとソモスの数列だということが分かります。
あとは漸化式に従って実装して、カンマ区切りで出力するという制約があるのでgroup_concatを用います。
with somos(a,b,c,d)as(select 1,1,1,1 union select (a*c+b*b)/d,a,b,c from somos limit 30)select group_concat(a,',') from somos where a>1;
ちなみに、stage2は本当はフィボナッチ数列にしようと思ってたのですが同じようなことをやっているサイトが見つかって没になりました。
フィボナッチ数列
WITH f(a,b)AS(SELECT 1, 0 union select a+b, a from f limit 90)SELECT a FROM f;
stage3はシェルピンスキーのキャスケットを出力する問題です。
この問題は想定解を作ってなくて(おい)部員の@satosと@nolzeさんの秀逸な解答を載せます。
@satos
with f(a) as (select 0 union select a+1 from f limit 4), m(k,w, y, x, c) as ( select 0,1,0,0,2 union select k+1,w*2,y+(a/2)*w,x+(a%2)*w,1+(c-1)*(a!=1) from m,f where k<6), s(t) as ( select group_concat(substr('.#',c,1),'') from (select x,y,k,c from m order by x) where k=6 group by y ) select t from s;
@nolze
WITH t(n,b1,b2,b3,b4) AS (SELECT 0,0x1000000000000000,0,0,0 UNION SELECT n+1, (~((b1>>0x4)&b1))&((b1>>0x4)|b1), (~((((b1&0x1)<<0x3c)|(b2>>0x4))&b2))&((((b1&0x1)<<0x3c)|(b2>>0x4))|b2), (~((((b2&0x1)<<0x3c)|(b3>>0x4))&b3))&((((b2&0x1)<<0x3c)|(b3>>0x4))|b3), (~((((b3&0x1)<<0x3c)|(b4>>0x4))&b4))&((((b3&0x1)<<0x3c)|(b4>>0x4))|b4) FROM t LIMIT 64) SELECT replace(replace(printf("%-016x%-016x%-016x%-016x",b1,b2,b3,b4),'0','.'),'1','#') FROM t;
@satosのは上から小さな三角形を作ってそれを下と右下にコピーして…みたいなことをやっていて、@nolzeさんのはセルオートマトンが大好きなのでルール90をエミュレートしています。
Are you smart??[misc]
問題
You can solve this problem even if you are NOT smart!!
Are_you_smart.pcapng - Google ドライブ
こんな感じの問題ファイルが与えられます。
これはスマホをパソコンに繋いで写真を転送した時のパケットキャプチャなのでプロトコルがUSBです。
5個しかパケットがなくて、3つめのパケットがやけにサイズが大きいことが分かります。
なんのパケットかな~と思って2つめのパケットを見ると、JFIFという文字があり、ここからjpegということが分かります。
データ部分をtsharkで抜き出します。
tshark -r Are_you_smart.pcapng -T fields -e usb.capdata > data
こんな感じになります。
普通のjpeg画像のヘッダ部分と見比べて、ちゃんとしたヘッダになるように2つめのパケットの先頭部分を削除して、3つめのパケットとバイナリとしてつなげようと思います。jpeg画像はff:d8..から始まっているのでそこまで削除して、一行にするとこのようになります。
これをjpegファイルにします。
`--> irb irb(main):001:0> a=`cat data`.split(":").map{|x| x.hex}.pack("C*");nil => nil irb(main):002:0> f=File.open("output","wb") => #<File:o> irb(main):003:0> f.write(a) => 52724
outputを開くとフラグが見えます。
HHKB!![networking]
問題
I had borrowed HHKB!! from my boyfiend :)
HHKB!!.pcapng - Google ドライブ
こんな感じのファイルが与えられます。
またもやUSBプロトコルです。
パケットをパタパタ見てみると、28パケット目あたりがパタパタ変わっていることが分かります。
タイトルのHHKBから、これはUSBキーボードとの通信なのかなと思います。
USB keyboard CTF..などとググっていると、TDUCTFの記事が出てきて、その中で言及されているUSB usage tableにたどり着きます。
53ページ目から、keyboard/keycode pageが始まり、"keycodes used in implementing a usb keyboard"の長い表があります。
データの0バイト目が02の時はシフトが押された状態で、2バイト目が2Aだとバックスペースだということに注意をして読んでいくと、入力された文字列はTSG{cookies}だということが分かります。
他にもeasyな問題たちを5個作りました。会場にはパソコン触ったことが無いような人も来るので、楽しめるようにと作りましたが意味わからんという反応が多かったです。。
一応やったことない人でもできるように解説も書いて、Githubにあるので暇な人は見てください。
簡単ではありますが、ARMなのでリバーシングはなかなか楽しいです。(なぜARMかというと、参加者のPCにラズパイを使ったから)