セキュリティ・キャンプ 2015 講義資料まとめ
セキュキャンに行けなかった人がセキュキャンの資料のまとめをつくりました.
公開してくださって本当にありがとうございます!
※ここにない資料があれば@y_hagまで教えてくださるととても嬉しいです.
#ssmjp で発表した―「進化するWebトラッキングの話」
2015/07/31に開催された#ssmjpにて,「進化するWebトラッキングの話」というタイトルで発表しました.
会場は品川のBIGLOBEのオフィスでした.
2015年07月の#ssmjpまとめ | ssmjp Infomation
発表スライド
オフレコのスライドは省いてあります.ごめんなさい><
結構身近な話題だったので,shlideshareのほうがそこそこbuzzってました.やはりみんな関心があるんだなあと.
この勉強会では過去に一度発表させていただいたことがあったので,今回は比較的落ち着いて発表出来ました.少し残念だったのは,時間があまりなかったこともあり,発表を聞いた人から質問,意見,マサカリをあまりいただけなかったこと.まだまだWeb初心者なので,色々とフィードバックをいただけたらと思います.
twitter上の評価を見ていると,「今後はCookieに取って代わって,Browser Fingerprintがトラッキングの主流になるということなのか」というコメントがありましたが,けしてそうではないと思います.スライドにもあるように,RTBといった広告システム等で今後もCookieは使われ続けると思いますし,Browser Fingerprintはあくまでユーザーを識別するための"補助的な"情報という立ち位置になると思います.一方で,今後それ単体だけでユーザーを特定できるような最強のFingerprintが見つかってしまうかもしれません(ないとおもいますが).
Webトラッキングは新しい話題がどんどんでてきますし,対策もまだまだ十分と言えないので,研究してみるには面白い題材だと思います.
Nginxのアクセスログを自動でSQLiteに出力する
先日Nginxを使ってWEBサーバを立ち上げたのだが,アクセスログを解析しやすいようにデータベースに突っ込みたかったので自分で実装してみた.sonickun.hatenablog.com
Apacheのログなどをデータベースに出力するツールとしてfluentd等があるようだが,導入が面倒そうだったのと,自分で自由にカスタマイズしたかったという理由で今回はpythonで書いてみる.
Nginxのアクセスログ
/etc/nginx/nginx.conf
によれば,Nginxのアクセスログのフォーマットは以下のようになっている.
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer"' '"$http_user_agent" "$http_x_forwarded_for"';
出力されたログの例は以下のとおり.
AA.BB.CC.DD - - [07/Apr/2015:03:36:34 +0000] "GET / HTTP/1.1" 200 1913 "http://sonickun.hatenablog.com/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36" "-"
また,ログファイルは以下のように1日毎に分割され,gzipで圧縮して/var/log/nginx/
下に保存される.
# ls /var/log/nginx/ access.log-20150405.gz access.log-20150406.gz access.log-20150407.gz access.log-20150408.gz access.log-20150409
実装
まずはログを格納するSQLiteデータベース(log.db)を/var/log/nginx/db/
下に作成する.
CREATE TABLE log( ip, remotelog, remoteuser, date, time, method, url, status, byte, refer, agent, xforwarded );
次に,ログファイルを読み込んでデータベースに出力するプログラムを作成する.
parse.py
import sqlite3 import datetime import gzip def parse(log, db): try: f = gzip.open(log, "rb") # decompress gzip conn = sqlite3.connect(db) cursor = conn.cursor() for line in f: data = [] a = line.split('"') line = line.split() #ip data.append(line[0]) #remotelog data.append(line[1]) #remoteuser data.append(line[2]) #date (ex. "07/Apr/2015" -> "2015/04/07") date = datetime.datetime.strptime(line[3][1:line[3].index(":")],"%d/%b/%Y") data.append(date.strftime("%Y/%m/%d")) #time data.append(line[3][line[3].index(":") + 1:]) #method data.append(a[1].split()[0]) #url data.append(" ".join(a[1].split()[1:])) #status data.append(line[8]) #byte data.append(line[9]) #refer data.append(a[-6]) #agent data.append(a[-4]) #x forwarded for data.append(a[-2]) try: cursor.execute( "insert into log values( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]) ) except Exception as e: print str(e) conn.commit() cursor.close() conn.close() f.close() print "Complete." except Exception as e: print str(e) if __name__ == "__main__": # extract filename d = datetime.datetime.now() d = d - datetime.timedelta(days=1) d = d.strftime("%Y%m%d") log = "/var/log/nginx/access.log-" + d + ".gz" db = "/var/log/nginx/db/log.db" print log + " -> " + db, parse(log, db)
ログファイルは収集した翌日の午前3時過ぎころに圧縮され保存されるようなので,このプログラムを毎日午前5時ころに実行するようにする.以下のようにparse.sh
を作成する.
parse.sh
#!/bash/sh
python parse.py
これをcronを使って実行をスケジューリングする./etc/crontab
を以下のように編集する.
/etc/crontab
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ 0 5 * * * root /var/log/nginx/src/parse.sh
これにより,毎日午前5時にparse.sh
が実行される.
出力結果
Nginxのログがデータベースに出力されているので,中身を確認してみる.
# sqlite3 log.db sqlite> select * from log limit 5; AA.BB.CC.DD|-|-|2015/04/07|03:36:34|GET|/ HTTP/1.1|200|1913|http://sonickun.hatenablog.com/|Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36|- AA.BB.CC.DD|-|-|2015/04/07|03:36:34|GET|/css/vendor/fluidbox.min.css HTTP/1.1|200|346|http://sonickun.xyz/|Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36|- AA.BB.CC.DD|-|-|2015/04/07|03:36:34|GET|/css/main.css HTTP/1.1|200|2753|http://sonickun.xyz/|Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36|- AA.BB.CC.DD|-|-|2015/04/07|03:36:34|GET|/js/vendor/jquery.fluidbox.min.js HTTP/1.1|200|1526|http://sonickun.xyz/|Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36|- AA.BB.CC.DD|-|-|2015/04/07|03:36:34|GET|/js/main.js HTTP/1.1|200|140|http://sonickun.xyz/|Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36|-
ログがデータベースに格納されている事がわかる.これで任意のSQL文を実行してさまざまな統計を行うことができるようになった.
VPSでWebサーバを構築した
先日のTDUCTF in ConohaでConoha VPSのクーポン券を頂いたので,遊び半分,勉強目的半分でWebサーバ(sonickun.xyz)を構築してみた.
Conoha VPS
今回VPSはConoha VPSを利用した.VPSの作成から管理まで,わかりやすいUIでとても簡単に行えた.www.conoha.jp
今回のVPSのスペックは以下のとおり.
- CPU: 2コア
- メモリ: 1GB
- HDD: 100GB
- OS: CentOS 6.5 (64bit)
これはConoha VPSの最小構成であり,お値段は月額930円とお手頃.
ユーザの設定
最初にログインした時はrootになっているため,一般ユーザを作成する.ユーザ名は仮に"hoge"とする.
# adduser hoge # passwd hoge
また,visudo
コマンドでsudoerを以下のように編集し,hogeがsudoを行えるようにする.
root ALL=(ALL) ALL hoge ALL=(ALL) ALL
SSHの設定
公開鍵認証でSSH接続を行えるように設定した.まずはssh-keygen
で公開鍵と秘密鍵のペアを作成する.
# ssh-keygen -t rsa
これにより,id_rsa(秘密鍵)とid_rsa.pub(公開鍵)のペアが生成される.サーバ側に公開鍵,クライアント側に秘密鍵を置くことにする.鍵の転送にはscp
を使った.
次に/etc/ssh/sshd_config
を以下のように編集する.
# rootでのログインを禁止する PermitRootLogin no # 公開鍵認証の設定 RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/id_rsa.pub # パスワードでの認証を禁止する PasswordAuthentication no
最後にsshdを再起動する.
service sshd restart
ドメインの取得
おなじみ「お名前ドットコム」を利用した.www.onamae.com
今回ドメインとして"xyz"を選んだのは次の理由から.
- セールで安くなってたから(1年で300円くらい)
- どんな用途にも使えそうなドメインだから
- 単純にカッコイイから.
ドメインの登録が完了するとwhois情報の登録などは代行でやってもらえる.管理画面のDNSレコードの設定でVPSのIPアドレスを登録し,Conoha側で逆引きの設定をしたら出来上がり.
Webサーバ
Nginx
WebサーバにはNginx(エンジンエックス)を使った.
Nginxの特徴としては,リバースプロキシとして動作することがある.ロードバランサとしても使えるし,HTTPSにも対応しているためSSL/TLSアクセラレータとして使用することもできる.また,画像やHTMLテキストといった静的コンテンツもキャッシュすることが可能.
Nginxのアクセス制御などのコンフィグは/etc/nginx/ngin.conf
に集約されており,簡潔に設定を行える.今回は,/etc/nginx/conf.d/server.conf
を作成し,このファイルを読み込ませるようにした.
/etc/nginx/conf.d/server.conf
server { listen 80; server_name sonickun.xyz; location / { root /var/www/html; index index.html index.htm; } }
これにより,sonickun.xyzにアクセスした時に/var/www/html
以下のindex.htmlが表示されるという設定になる.
Bootstrap
またWebフレームワークとして,Bootstrapを用いた.BootstrapはHTML5・CSS3・jQueryを使用したフレームワークであり,レスポンシブデザインにも対応している.また多彩なパッケージやテンプレートが存在し,デザインの能力があまりなくてもそこそこカッコイイサイトが作れる.getbootstrap.com
「Bootstrap テンプレート」などで検索するといろいろ出てくるので,その中からシンプルで良さげなものを選んだ.
これでほとんど雛形が完成してるので,あとは適当にHTMLを自分なりにアレンジするだけ.
所感と今後の予定
Web初心者なのでサーバを構築しながらいくつも知見を得ることができてよかった.実際に自分で手を動かしたほうが理解が深まる.
今後の予定としては
- ファイアウォールの設定を見直す
- CTF用のサイトを作る
- パケットキャプチャしてパケットを愛でる
などを考えている.
TDU CTF 2014 Satellite in ConoHa ― Write-up
TDU CTF 2014 Satellite in ConoHaに参加した。結果は1000点くらい(覚えていない)で15位くらい(覚えていない)だった。上位の人達を見てみると、GEKI-YABAな人たちが名を連ねていた。
Write-up
EasySQLi Challenge
SQLインジェクションの問題。Webサイトの入力フォームに"(ダブルクオート)などを入力するとSQLエラーが表示され、SQLiが可能であることがわかる。"or "1"="1
を入力するとテーブルの情報がすべて表示されるが、フラグはない。フラグは別のテーブルにあると思い、" OR 1=1 UNION SELECT sql, 1 FROM sqlite_master;--
を入力してスキーマ情報を抜き取る。
CREATE TABLE "ok_flag_is_here"(title varchar(48), body varchar(256)) CREATE TABLE flagTable(title varchar(48), body varchar(256)) CREATE TABLE questionTable(title varchar(48), body varchar(256))
"ok_flag_is_here"とflagTableというテーブルがあるので、" OR 1=1 UNION SELECT title, body FROM "ok_flag_is_here";--
と" OR 1=1 UNION SELECT title, body FROM flagTable;--
でフラグが2つ得られた。
テーブルの中にURLがあり、そこに移動するとステージ2のページが現れる。こちらはMySQLであることがわかったので、" or "1"="1";#
で3つ目のフラグが得られた。ただフラグの文字列は白塗りされており見つけくくなっていた。一応" UNION ALL (SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES) ;#
でスキーマ情報を抜くことはできたがこの先にフラグはあったのだろうか。
Simple Uploder
ウェブサイトからサーバへ任意のファイルがアップロードできるようになっている。phpファイルをアップロードすれば実行してくれるのかなーと思い、HelloWorldなプログラムを送ったらやはり実行された。つまりは任意のコードのが実行できるということなので、以下のようにls -l
をするプログラムを送る。
<?php $command = 'ls -l'; $output = shell_exec("{$command} 2>&1"); print_r ($output); ?>
すると、参加者がアップロードしたファイルの中に一つだけ更新日時の古いPNGファイルを見つけたので、これを表示させる。
<?php $image_path = './dc3db649f63cc360174b2ea7e470ee40.png'; header('Content-Type: image/jpeg'); readfile($image_path); ?>
これで1つ目のフラグをゲット。さらに先ほどのプログラムを使ってcat /etc/passwd
を実行したところ、passwdファイルの中に2つ目のフラグがあった。
SUPER ULTIMATE COOL SECURE NOTING SYSTEM
adminのログイン画面でuserに"or "1"="1
を入力するとログインができ、1つ目のフラグが得られる。2つ目のフラグはadminのパスワードとの事だったので、ブラインドSQLiかなと思ったところで断念。後で聞いた話によるとSearchのところからSQLiでパスワードが得られたらしい。
Developer! Developer! Developer!
暗号化されたzipファイル(question.zip)が渡される。中にはflag.txt(1KB)とSteve_ballmer_2007_outdoors2.jpg(295KB)があることがわかったので、Steve_ballmer_2007_outdoors2.jpgが手に入れば既知平文攻撃ができるなと思った。ファイル名でググったらすぐ出てきたのでここからダウンロードする。既知平文攻撃にはpkcrackをつかう。pkcrackは32bit WindowsとLinuxで動作するが、なぜかWindowsでは解凍できなかった。Linux上で以下のコマンドでフラグを得た。
$ pkcrack -C question.zip -c Steve_ballmer_2007_outdoors2.jpg -p Steve_ballmer_2007_outdoors2.jpg -d target.zip $ unzip target.zip $ cat flag.txt
読めない文字1
BASE64な文字が渡された。文字を2回デコードしたところフラグが得られた。
unknown file
3B14EA88FCDB58239928D829DD5182E23D866255というASCII textのファイルが渡される。Trip Pictureと同様stringsとgrepでフラグを見つけた。
柚子胡椒 Vol.1
bluetooth.pcapというpcapファイルが渡される。bluetoothのパケットうわぁ…とおもったがstringsとgrepでフラグが得られたので結局中身を見ていない。
Evidence
RawImageというイメージファイルが渡される。FTK Imagerでマウントして中身を見ると、"!oc.pdf"というPDFファイルを見つけたのでこれをエクスポートして開いたらフラグが得られた。
misc
覚えてません ;)
所感
初心者向け(?)のCTFなだけあって、たくさん問題が解けて楽しかった。確実に解かなければならない問題をしっかり解けたのは良かった。ただ得意なはずのNetwork問題で見たことがないパケットが出てきて解けなかったのは辛かった。いつものことながらbinary系の問題を敬遠してしまったので、後でしっかり解こうと思う。
運営の皆様、ありがとうございました!
#ssmjp で発表した ―「ダークネットのはなし」
"深淵を覗き込む時、深淵もまたこちら側を覗き込んでいるのだ。"
2015年2月20日のssmjpという勉強会でダークネットについて発表させていただきました.(会場は品川のBIGLOBEのオフィス)
「ダークネット」という,なんとも厨二くさいワードですが,れっきとしたネットワーク用語です.
インターネットのダークサイドへようこそ...
会場で寄せられた質問は以下のとおり.
Q.IPアドレスがダークネットか否かを判断する方法はなにか
A.あらゆるリクエストパケットを投げてみて,なにも応答がなかったらダークネットと考える.
Q.ダークネットと経路なしの区別はなにか
A.ダークネットはパケットが「到達可能」なのに対して,経路なしはパケットが「到達不可能」なもの.到達不可能とはルータの先に経路情報がなくパケットが到達し得ない状態のこと.
Q.一時的にサーバーダウンして応答を返さないIPアドレスもダークネットに含まれるか
A.そういったIPアドレスもダークネットの定義に当てはまる.ダークネットの領域は日々変化するものと考えてよい.
Q.ダークネットのデータセットは公開されているのか
A.今回使用したNICTER Darknet DatasetはMWS(マルウェア対策研究人材育成ワークショップ)で大学等の研究者向けに提供されているものであり,一般に公開はされていない.データの解析はNICTが管理するVM上で行う.(参考:マルウェア対策研究人材育成ワークショップ 2014 (MWS2014))
Q.IPv6のダークネットにおいても同様にパケットは観測され,サイバー攻撃の傾向分析に役立つか
A.IPv6のダークネットでもパケットは観測されるとは思うが,IPv4のようにアドレス空間全体をスキャンしようと考える人はほとんどいないのではないかと思うので,その数は少なく,傾向分析は難しいのではないかと考えている.攻撃者としては,スキャンをする際はある程度ターゲットに当たりをつけてスキャンするはず.
他にも「スキャンされにくいようなネットワーク構築を心がけるべき.セグメントは大きく分割しすぎない.」などのご意見も頂きました.議論に参加してくださった方々,本当にありがとうございました.
※DAEDALUSの解説,NTP/DNS amp 攻撃の解説,スキャンツールの解説等は口頭で済ませてしまったためスライドにはありません(また別の機会に).アップロード版の自己紹介スライドではなんとなく本名は伏せてあります.
発表についての感想
ssmjpはこれまで2回ほど参加していて,今回初めて発表側に立たせていただきました.今回はいつもより学生が少なくほとんどが社会人のプロな方だったので若干緊張しました.とくに質疑応答の時は慌てずもっと落ち着いて答えられるようになりたいです(若干的はずれな回答もしてしまった気がして反省している).また,「ダークネットおもしろい!」という言葉をたくさん頂けたことは嬉しかったです.アウトプットはホント大事だなあと実感したので,今後も精進してまた何かしらの勉強会で発表できたらと思います.
SECCON CTF 2014 決勝戦に出場した
SECCON CTF 2014 決勝戦にチームm1z0r3(みぞれ)として出場してきました.結果は431点で24チーム中20位,日本チームでは10位でした.SECCON CTF 2014決勝戦・全国大会カンファレンス
SECCON CTF 2014 Finals Ranking
特別賞として,「Medical × Security Hackathon賞」を頂きました.3月に福島で行われるハッカソンに招待していただけるようです.
圧倒的実力不足を痛感しました.Writeupが書けない.
個人的に取り組んだ問題について書いていこうと思います.問題サーバは全部で6台ありましたが,主にWEB系の問題を中心にに1,2,5,6に取り組みました.
サーバ 壱
指定されたURLにアクセスするとユーザ登録とログインが出来るようになっている.
ログインすると以下の画面が開く.各チームごとにUser NameやURLに使えない文字のブラックリストが作れるようになっている.
このサーバでは登録したユーザ数が最も多いチームにDefenseポイントが入るようになっている.ただし短時間に連続して登録できないようになっており,さらにブラックリストもかいくぐらないといけないため工夫が必要.
Attackポイントを取るにはページ下部にあるのSendフォームが狙い目のよう.ここで指定されたURLに管理者がアクセスしてくる.実際に手元(192.168.6.9)にWEBサービスを立ち上げ,http://192.168.6.9/
を指定するとGETでアクセスしてくるがとくに管理者のセッション情報はない(クロスドメインの問題がある).HTTPヘッダのUser-Agentに"Admin's Browser"の文字を発見したのでこのUAでアクセスしたがなにも起きなかった.Sendの下にShow Passwordのフォームがあるので一旦管理者にここをアクセスさせてからごにょごにょ...といろいろ考えたがここで挫折.あとで聞いた話によるとXSSが可能だったらしい.
サーバ 弐
以下のようなキャプチャ認証がある掲示板がある.
画面下には直近の投稿履歴が表示される.一定時間ごとにこの履歴欄に表示されているチームにDefenseポイントが入る.他のチームはこの投稿を並列処理で自動化してがっぽり点を稼いでいた(ほぼDDoS攻撃の状態だった).なお自動化の際にはキャプチャの画像を見る必要はなく,cookieの設定の脆弱性を突いて認証を突破することが可能らしい.うちのチームは自動化ができなかったのでなんとか脆弱性を突いてAttackポイントをば,と思っていたが,後で投稿数が最も多いチームがフラグを得ていたことを聞き,「なんだそれ」と言った.
bodyではダブルクオート,"script","alert"などの文字がエスケープされたり,imgタグなどが埋め込めたりなど,とっても思わせぶりな挙動をしてくれたのにXSSは全く関係なかった.
サーバ 伍
CGIが動いていて,最初の画面がこのような表示になる.
ここに自分のチームのDefense Keyを置くことでDefenseポイントが入るようになっている.後にKeyは/flags
下にあることがわかった.直感的にいま流行りのShellshockの攻撃でコマンドインジェクションができるかなと思ったができなかった.
次にこのWEBサーバーのIPアドレスが10.100.5.2なのだが,終端が1でなく2な時点で怪しい./24でネットワークスキャンを行ったら他にも10.100.5.102,10.100.5.202,10.100.5.252も動いてることがわかった.しかもそれぞれポートがごっそり開いていて更に怪しい.全てのサーバ,全ての空いてるポートに対してnetcatするスクリプトを書いて試したがHTTPの80番ポート以外は反応はなし.ほかにもApacheの脆弱性を調べたりURLをごにょごにょしてみたが何も見つけられずここで頓挫.
以下,終了後に聞いた話だが,まず/key.txt
に一つ目のAttackポイントのフラグがあったらしく,「なんだそれ」と言った.こういう問題が今後の大会でも出るのかなと思うと少しつらい.ところがチームdodododoのakiymさんはこういうCTFでありがちなURLを試行するスクリプトを用意して見つけたらしく,プロは違うなと思った.ほかには/cmd.sh
や/svn/flags
が存在したらしく,Defense Keyが送信可能だったらしい(参考:SECCON 2014 全国大会に出た - misodengakuのブログ).これを解いたチームはほとんどいなかった模様.
追記(2015/02/16)
他の人のWriteupを見て,実はこの問題はガッツリNetworkな問題だということがわかった.じつは5つ目のサーバが存在し,パケットをよく監視しているとそれに気づくことができるという./key.txtの存在もその流れで知ることができる.こういうことに気づけないようではパケリストとしてまだまだだなあとおもう.
問題の詳細についてはもりたこさんのブログを参照されたい
サーバ 六
暗号の問題.平文と暗号文の対応を見て暗号化のアルゴリズムを読み解き,Keyとなる暗号文を解読する.問題は全部で4問ある.1~3問目までは素直な問題だったらしく,チームの先輩がすぐに解いてくれた.4問目はかなりの難問で,自分も加わって協力して解いた.
暗号文は以下のとおり.
AAAAgBX7KsK03QWS3Leud1FmWe5LyodjFstpL6Eo1JFKpioWItFrXBdrv6Vrf9ZwOK3TmBqriKkisDVXD/E45TcNOQUwNumw8L8pNiO4vLfxzsz6FYGDMB25IvYwO2ZI6qzbhOMi4dfSGkQfd8h5YAB
平文と暗号文の対応のサンプルは以下のとおり.
ede AAAAA1lsiAB edb AAAAA1iWSy8AA dbac AAAABCw2JY7JpAB
まず,暗号文に使われる文字は大文字,小文字のアルファベットに加え,"_"と"/"の全部で64種類であることがわかった.これはBASE64と同じで,全ての文字を6bitで表現できるため,BASE64の変換表を用いて文字を全て2進数になおした.
ede 000000000000000000000000000000110101100101101100100010000000000001 edb 000000000000000000000000000000110101100010010110010010110010111100000000000000 dbac 000000000000000000000000000001000010110000110110001001011000111011001001101001000000000001
01に直すと前半分は文字列長を表す領域になっていて,中盤部分は出現する文字をASCII変換したものが出現頻度順に並んでいた.後半部分は文字の並びを表現しているようだったが,途中でハフマン符号っぽいことに気づいた.
ところが平文を一つ一つ手作業で符号化していくと,文字の種類が多い時にハフマン木が思ったとおりにならない.ここでこの符号化はハフマン符号に似たシャノン符号ではないかと思ったらビンゴで,チームの先輩がコードを書いて復号してくれた.
暗号文を複合した結果は以下のとおり.
Password_located_you_done_of_you_that_mailing_and_C/C_Japanese_I_university_of_fend_time_used_Free_Basic_at_get_take_in_debug_Li
所感
自分の実力不足を痛感した大会だった.自分は端から比較的得意なWEB問題を担当するつもりだったが,点数に直結する貢献がまったくできなかった.また序盤にDefenseに取り組んだチームが大きくリードしたように思えたが,うちのチームは1日目にDefenseポイントがまったく取れず,2日目に追い上げるのが困難な状況となってしまった.戦略によってはもう少し点も取れたかも知れない.
一方で,みんなで協力して議論しながら問題を解いたことは嬉しかったし楽しかった.とくに6番目の暗号のwriteupは簡単に書いたが,あれは徹夜して紙に起こした0と1の羅列をひたすら眺めてみんなで解いた問題だった.あの感覚を忘れず今後もCTFを続けていきたい.
ちなみに私は来年度からのm1z0r3の次期代表を拝命したので,そういった面でも頑張って行きたい.