SANS NETWARS 2016に参加しました
SANS NETWARSトーナメント2016 | イベントのご案内 | 情報セキュリティのNRIセキュア
8/19(金) 〜 8/20(土) に開催された,SANS NETWARS 2016に参加してきました.
SANS NETWARSは,今年で2回目の参加です.
1日目に講義を受け,2日目にCTFをやるという日程で,充実した内容でした.
内容の公開はNGなので,詳しくは書けませんが,去年の内容よりもボリュームが増えていたし,CTFの問題もすべて変更されていて新鮮な気持ちで取り組めました.
去年は2日目のCTFの順位が32位だったので,今年は20位ぐらいを目指そうと思っていました.
結果は,23位でした.それなりに目標に近く悪くない結果だったと個人的には思います.
もう少しで解けそうだった問題が1問あったので,それだけが心残りです.来年も開催されれば,リベンジしに行きたいと思います.
チーム戦になるかもしれないという話もあったので,足を引っ張らないように今から精進したいと思います.
Ubuntu 14.04+nginxでHTTP2なWebサーバを建てたと思ったらChromeに対応できてなかった話
特にコンテンツもないけど,唐突にWebサーバを建てたくなったので,建てることにしました. せっかくなので,HTTPS,HTTP2にも対応する感じで.
HTTPS,HTTP2に関わるnginxの設定は,セキュリティミニキャンプin北海道で学んだし,そんなに詰まることもなく終了. 証明書はLet's encryptを用いて発行しました.
手元のFirefoxからアクセスし,それぞれ設定が反映されていることが確認できたので,「これで終わったぞー」と思っていたらChromeからだとHTTP2になっていない様子.
調べてみると,古いバージョンのOpenSSL(1.0.1以前)を使用している場合,Chrome(build 51以降)でHTTP2でのアクセスができなくなるようです.
ALPNというTLSの拡張に対応していないのが問題みたい.
ALPNについては,こちらのサイトがわかりやすかったです.
そういうわけで,OpenSSL 1.0.2の導入とnginxの再コンパイルをしました.
情報セキュリティスペシャリストになりました
セキュキャンに落ちてから,かなりナーバスになっていましたが,数日後に情報セキュリティスペシャリストの合格発表があったので,一応確認したら受かっていました.
勉強方法
情報セキュリティスペシャリスト(高度情報処理技術者試験)になりました - kumar8600の日記
こちらの記事を参考にしました.
実は参考書は買ったものの,ほとんど読んでおらず,なんで受かったんだろう…という気持ちです.午後問に至っては当日の朝方まで初見でした. 多分,普段からセキュリティの勉強をしていれば特別な対策はせずとも受かると思います.
失敗談
前回の情報処理技術者試験で応用情報技術者に受かっていたのに,午前Ⅰの免除を申請していませんでした.セキュリティ分野の勉強ばかりして他を怠っていると,最大の障壁になり得るので,これから受ける人は可能であれば免除申請したほうが良いと思います.
セスペがなくなるらしい
ニュース - 情報セキュリティスペシャリスト合格者は「情報処理安全確保支援士」試験免除へ:ITpro
情報処理安全確保支援士試験になるらしいですね.長いし画数が激増しているので,手書きでは書きたくないです.
心の叫び
セスペいらないからセキュキャン参加したい
— げん@セキュキャン落ちスペシャリスト (@neglect_yp) 2016年6月17日
セキュリティ・キャンプ全国大会2016の応募用紙を晒す
今年も死んだよ。選択問題だけ晒す。
選択問題. 1
hogeはローカル変数であり、int型の10個ぶんの配列である。main関数の中でスタックポインタ(rsp)がずらされることにより、必要なサイズ(sizeof(int)*10bytes)
がスタック上に確保される。C言語で配列名は配列の先頭アドレスを指すので、hogeにはスタック上に確保されたメモリの先頭アドレスが格納されていることになる。よって、0x7fff539799f0
付近はスタックのアドレスであることがわかる。
fugaはintポインタとして宣言されており、malloc()
により動的に確保されたメモリのアドレスが格納されている。malloc()
はヒープ上にアドレスを確保するので、0x7fca11404c70
付近はヒープのアドレスであることがわかる。
選択問題. 2
- HTTPS
Webブラウザのアドレスバーに書かれている、スキーマからHTTPSを用いていることがわかる。Firefoxでは、ページ内で右クリック→ページ情報の情報を表示→「セキュリティ」タブと操作することで、より詳しい内容が表示できる。この内容から、認証局が「Google Inc」であることや、暗号化の方式が「TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256」であることがわかる。 - Cache-Controlヘッダ
Firefoxでは、ツール→Web開発→ネットワークと操作することで、Webサーバとのやりとりを詳しく見ることができる。その中で、サーバからの応答の中に、「Cache-Control: "private, max-age=0"」というヘッダがあることがわかる。privateのほうは、コンテンツが複数のユーザで共有するキャッシュに記録されるべきでないことを示している。max-age=0は変更をその都度確認させるための指定だ。「Expires: "-1"」というヘッダもあり、これは「Cache-Control: "max-age=0"」と同様の記述らしいが、ブラウザによっては片方しかサポートしていないため、両方書かれているらしい。 - X-Frame-Optionsヘッダ
「X-Frame-Options: "SAMEORIGIN"」というヘッダがあることから、自身と生成元が同じフレーム内に限り、ページを表示することができる。これによって、<iframe>タグなどを用いたクリックジャッキング攻撃を防止することができる。 - X-XSS-Protectionヘッダ
「X-XSS-Protection: "1; mode=block"」というヘッダがあることから、IEのXSSフィルターが有効になることがわかる。有効にするだけなら、「X-XSS-Protection: "1"」だけでよいのだが、mode=blockを指定することでより強固になる。過去のバージョンのIEでは、XSS Filterでブロックしたスクリプトをそのままブラウザ上で表示していた。これによって、XSS Filterを利用したXSSが生まれてしまった。現在はmode=blockがなくても、直接ソースが表示されるようなことはないようだが、過去のブラウザを利用している人も多いだろうから、mode=blockが指定されているのだと思う。
選択問題. 6
'や"など、SQLのメタ文字を入力してみる。なぜならば、IDとパスワードを入力してユーザ認証を行っているWebアプリは、大抵の場合、裏でデータベースにアクセスし、問い合わせの結果でログインの可否を判断しているからだ。もし、入力サニタイズが不十分であるなら、エラーが表示されるはずだ。そうなれば、SQLインジェクションができる可能性があり、大きな脅威となる。
選択問題. 8
まず、この逆アセンブルを眺めて気づいたのは、この逆アセンブルが大きく2つの部分に分かれることです。 0x400080...0x4000fcは、主にpushq命令で構成されていて、 0x400101...0x40012eは、主にretq命令、pop命令で構成されています。 脳内で上から順番に実行してみると、ROPのような挙動をすることがわかりました。 すなわち、0x400080...0x4000fcで戻りアドレスやレジスタにセットする値をスタック上にpushしておき、 0x400101...0x40012eでretqをjmp、popをmovのように使用しています。 したがって、これはROPを応用し、難読化が施されたバイナリの逆アセンブルであることがわかりました。 若干読みにくいので、手動で難読化を解除してみることにしました。
mov $0x0,%rax mov $0x0,%rdi mov %rsp,%rsi mov $0x0,%r10 mov $0x8,%rdx syscall ;read(STDIN,%rsi,0x8,0) mov $0xffffffffffffffe0,%rbp mov $0x7,%rcx xorb $0x55,(%rsi,%rcx,1) ;-> 標準入力から受け取った文字列の最後の文字と0x55のXORをとっている。 ; decが0x7->0x0までループする dec %rcx xorb $0x55,(%rsi,%rcx,1) ; ループここまで mov $0x0,%rdi movabs $0x63391a67251b1536,%rax cmp %rax,(%rsi) mov 0x3c,%rax (jne $0x40012c ;もし入力のすべての文字を0x55とXORした結果が$0x63391a67251b1536と一致しないなら) (syscall ;一致した時の処理, exit(0)) mov $0x1,%rdi syscall ;exit(1)
若干不整合がある気がしますが…
- 基本的には、標準入力から8文字受け取り
- すべての文字を
0x55
とXORをとった結果に変更し、 0x63391a67251b1536
と比較する(リトルエンディアンなことに注意する)- 一致していれば、
exit(0)
、していなければexit(1)
というプログラムのようです。
すなわち、"c@Np2Ol6"
という入力であれば、正常終了するプログラムであるということがわかりました。
(Pythonのインタプリタで、0x63391a67251b1536
をpackして、listにして、mapして...として求めました。
xorb $0x55,(%rsi,%rcx,1)
がどういう処理をするのか、最初わかりませんでしたが、
rasm2を用いてintel記法にしてみると、xor byte [rsi + rcx], 0x55
となり、理解できました。
正直、ループのところはあまりちゃんと読んでいないのですが、decとjneがあることから、%rcxが0まで回るループだろうなと断定して読み進めた結果、それらしい感じになりました。
CTFのような問題で、非常に楽しめました。個人的には一番好きな設問です。
提出前の僕
「選択問題 【8】」に機種依存文字、絵文字などが含まれています。[〜〜〜〜〜]
— げん@セキュキャン落ちた (@neglect_yp) May 30, 2016
となっているが、みつからず死んでいる
— げん@セキュキャン落ちた (@neglect_yp) May 30, 2016
犯人は"〜"でした
— げん@セキュキャン落ちた (@neglect_yp) May 30, 2016
@__x90__ 一行だけしか表示されなかったため、[〜〜〜〜〜]が、〜で引っかかっているということに気づくのに時間かかった
— げん@セキュキャン落ちた (@neglect_yp) May 30, 2016
〜とかいう文字もう一生使わねえからな
— げん@セキュキャン落ちた (@neglect_yp) May 30, 2016
その後
セキュキャン落ちました…
— げん@セキュキャン落ちた (@neglect_yp) 2016年6月14日
来年も一応応募資格はあるけれど、これで3回落ちているし最早受かる気がしないので迷っている。
スタックとメモリ解放の話
Twitterで、とあるコードについて話題になっていたので、まとめてみる。
問題のコード
#include <stdio.h> int* func(){ int a = 114514; return &a; } int main(){ printf("%d\n", *func()); }
結論としては、動作は未定義である。環境によって挙動が変わる。 ということらしいが、実際にはどのような挙動をする可能性があるのだろうか。
様々な挙動
114514
と表示される
私が普段使用している環境だと、この挙動を示した。 「局所変数a
の領域がページアウトされていない」かつ、「printf()
の呼び出しの際、引数や局所変数で上書きされていない」場合にこの挙動を示す。Segmentation fault
wandbox(C++コンパイラ)で確認した挙動。「局所変数コンパイラがnull返すようにしてくれていたようです。Thanks, うさぎさんa
がページアウトされていた」場合にこの挙動を示す。別の値が表示される
「printf()
呼び出しの際に、引数や局所変数で上書きされた」場合に起こりうる。 未確認。
追記:gcc 4.9以前と5.1以降で変わるらしい。5.1以降だとnullを返すようになる。 d.hatena.ne.jp
感想的な
そもそも、CとかC++はコードの安全面はプログラマに任せているというような話を聞いた気がするし、 こんなコード書くなという話なんだけれど…
こういった、未定義のコードの挙動について考えてみるのって楽しい。もっと探ってみたい。
DionaeaFRの導入で困った話
- 先日、ハニーポットにDionaeaFRを導入したのですが、結構導入に詰まった上、あまり資料も見かけなかったので、メモ程度に自分が詰まったところを残しておきます。
そもそも、DionaeaFRって?
- DionaeaFRは、Dionaeaで取得したlogsql.sqliteをWebでグラフィカルに見ることができるようにするものです。
- Webフロントエンドとか言うんですかね?その辺の用語の定義が曖昧なもので…
- こんな感じ。
- Djangoとかで動いているようです。Djangoはあまり詳しくないので、そのあたりでも結構詰まりながら、試行錯誤してどうにか導入しました。
Node.jsといい、Djangoといい、バージョン周りの依存関係なんとかしてくれ
早速導入してみる
導入環境
参考記事
- Visualizing Dionaea's results with DionaeaFR - BruteForce Lab's Blog
- 基本的には上記記事の通りで良いので、差分だけ。
バージョン周り
0) apt-get
で入るpipが古い+pip install -U hoge
しても"owned by OS"~などと言われ、死ぬ。
- sixのバージョンが古いようで、
pip install -U six
しても"owned by OS"~- pip自体の更新も同様。
easy_install
でpipを更新すると良いらしい。
# easy_install -U pip
1) Djangoのバージョンを指定する
# pip install "Django==1.8.11"
- 1.7以前でも死ぬし、1.9以降でも死んだ。
2) Node.jsのバージョン
cd /opt/ wget http://nodejs.org/dist/v0.10.42/node-v0.10.42.tar.gz tar xzvf node-v0.10.42.tar.gz cd node-v0.10.42 ./configure make make install
- lessが10.40以降を要求してくるので、10.42を入れた。
- 今回の話とはあまり関係ないですが、こちらも参考になると思います。February 2016 Security Release Summary | Node.js
実際に動かす
- 起動コマンドを叩くと、migrateしてね的なことを言われました。
- 言われるがまま、
python manage.py migrate
としておきました。 - 多分、環境が変わった時に叩く用のやつなのかな?
- 言われるがまま、
動いたと思ったら
- ブラウザを起動して、
ハニーポットのIP:8000
にアクセスすると、グラフ等が表示されると思います。- 左側のメニューから、Connections, Downloadsを選択すると、エラーメッセージが表示されました。
- nospacelessというタグがねえぞと言われているようです。
/opt/DionaeaFR/DionaeaFR/Templates/table.html
から、nospacelessタグと、その終了タグをすべて消すと、うまくいきました。- 表示がおかしくなるかなと思いましたが、大丈夫そうです。
sed
が好きな方は、sed
を使うと楽だと思います。3個程度だったので、私は手で消しました。
- 左側のメニューから、Connections, Downloadsを選択すると、エラーメッセージが表示されました。
感想的な
UIがかっこいいので、それだけでも十分使う価値があるんじゃないかなと思います。Dionaeaはシミュレートするサービスが多いので、グラフィカルに見れるのは嬉しいです。ただ、DionaeaFRの動いているポートへのアクセスもDionaeaが記録してしまい、ログが自分のアクセスが埋まるというアクシデントが発生しているので、そのあたりの対処も今後していきたいです。