Gen's blog

CTFとか、競プロとか、その他諸々

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の再コンパイルをしました.

Chromeからアクセスすると,青い稲妻が表示されて,万事解決.

情報セキュリティスペシャリストになりました

セキュキャンに落ちてから,かなりナーバスになっていましたが,数日後に情報セキュリティスペシャリストの合格発表があったので,一応確認したら受かっていました.

勉強方法

情報セキュリティスペシャリスト(高度情報処理技術者試験)になりました - kumar8600の日記

こちらの記事を参考にしました.

実は参考書は買ったものの,ほとんど読んでおらず,なんで受かったんだろう…という気持ちです.午後問に至っては当日の朝方まで初見でした. 多分,普段からセキュリティの勉強をしていれば特別な対策はせずとも受かると思います.

失敗談

前回の情報処理技術者試験応用情報技術者に受かっていたのに,午前Ⅰの免除を申請していませんでした.セキュリティ分野の勉強ばかりして他を怠っていると,最大の障壁になり得るので,これから受ける人は可能であれば免除申請したほうが良いと思います.

セスペがなくなるらしい

ニュース - 情報セキュリティスペシャリスト合格者は「情報処理安全確保支援士」試験免除へ:ITpro

情報処理安全確保支援士試験になるらしいですね.長いし画数が激増しているので,手書きでは書きたくないです.

心の叫び

セキュリティ・キャンプ全国大会2016の応募用紙を晒す

今年も死んだよ。選択問題だけ晒す。


選択問題. 1

hogeはローカル変数であり、int型の10個ぶんの配列である。main関数の中でスタックポインタ(rsp)がずらされることにより、必要なサイズ(sizeof(int)*10bytes)がスタック上に確保される。C言語で配列名は配列の先頭アドレスを指すので、hogeにはスタック上に確保されたメモリの先頭アドレスが格納されていることになる。よって、0x7fff539799f0付近はスタックのアドレスであることがわかる。 fugaはintポインタとして宣言されており、malloc()により動的に確保されたメモリのアドレスが格納されている。malloc()はヒープ上にアドレスを確保するので、0x7fca11404c70付近はヒープのアドレスであることがわかる。

選択問題. 2

  1. HTTPS
    Webブラウザのアドレスバーに書かれている、スキーマからHTTPSを用いていることがわかる。Firefoxでは、ページ内で右クリック→ページ情報の情報を表示→「セキュリティ」タブと操作することで、より詳しい内容が表示できる。この内容から、認証局が「Google Inc」であることや、暗号化の方式が「TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256」であることがわかる。
  2. Cache-Controlヘッダ
    Firefoxでは、ツール→Web開発→ネットワークと操作することで、Webサーバとのやりとりを詳しく見ることができる。その中で、サーバからの応答の中に、「Cache-Control: "private, max-age=0"」というヘッダがあることがわかる。privateのほうは、コンテンツが複数のユーザで共有するキャッシュに記録されるべきでないことを示している。max-age=0は変更をその都度確認させるための指定だ。「Expires: "-1"」というヘッダもあり、これは「Cache-Control: "max-age=0"」と同様の記述らしいが、ブラウザによっては片方しかサポートしていないため、両方書かれているらしい。
  3. X-Frame-Optionsヘッダ
    「X-Frame-Options: "SAMEORIGIN"」というヘッダがあることから、自身と生成元が同じフレーム内に限り、ページを表示することができる。これによって、<iframe>タグなどを用いたクリックジャッキング攻撃を防止することができる。
  4. X-XSS-Protectionヘッダ
    「X-XSS-Protection: "1; mode=block"」というヘッダがあることから、IEXSSフィルターが有効になることがわかる。有効にするだけなら、「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)

若干不整合がある気がしますが…

  1. 基本的には、標準入力から8文字受け取り
  2. すべての文字を0x55とXORをとった結果に変更し、
  3. 0x63391a67251b1536と比較する(リトルエンディアンなことに注意する)
  4. 一致していれば、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のような問題で、非常に楽しめました。個人的には一番好きな設問です。


提出前の僕


その後

来年も一応応募資格はあるけれど、これで3回落ちているし最早受かる気がしないので迷っている。

スタックとメモリ解放の話

Twitterで、とあるコードについて話題になっていたので、まとめてみる。

問題のコード

#include <stdio.h>

int* func(){
    int a = 114514;
    return &a;
}

int main(){
    printf("%d\n", *func());
}

結論としては、動作は未定義である。環境によって挙動が変わる。 ということらしいが、実際にはどのような挙動をする可能性があるのだろうか。

様々な挙動

  1. 114514と表示される
    私が普段使用している環境だと、この挙動を示した。 「局所変数aの領域がページアウトされていない」かつ、「printf()の呼び出しの際、引数や局所変数で上書きされていない」場合にこの挙動を示す。

  2. Segmentation fault
    wandbox(C++コンパイラ)で確認した挙動。 局所変数aがページアウトされていた」場合にこの挙動を示す。 コンパイラがnull返すようにしてくれていたようです。Thanks, うさぎさん

  3. 別の値が表示される
    printf()呼び出しの際に、引数や局所変数で上書きされた」場合に起こりうる。 未確認。

追記:gcc 4.9以前と5.1以降で変わるらしい。5.1以降だとnullを返すようになる。 d.hatena.ne.jp

感想的な

そもそも、CとかC++はコードの安全面はプログラマに任せているというような話を聞いた気がするし、 こんなコード書くなという話なんだけれど…

こういった、未定義のコードの挙動について考えてみるのって楽しい。もっと探ってみたい。

サークルのLT会でDionaeaの話をした

所属しているサークルで、毎年新入生の歓迎と自己紹介を兼ねてLT会をしている。内容は技術的な内容でもそうでなくても自由。春休みにハニーポットを動かし始め、MySQLへの攻撃で面白そうなログがあったので、それについて話してみた。

上のスライドは、実際に使用したスライドを若干改変している。

新入生歓迎を兼ねていることもあり、マルウェアの逆アセンブルを読んだり、動的解析したり〜というような内容ではなく、表層だけさらっと見た感じにしている。

落ち着いたら、取得したマルウェアを解析して、改めて記事を書きたい。

DionaeaFRの導入で困った話

  • 先日、ハニーポットにDionaeaFRを導入したのですが、結構導入に詰まった上、あまり資料も見かけなかったので、メモ程度に自分が詰まったところを残しておきます。

そもそも、DionaeaFRって?

  • DionaeaFRは、Dionaeaで取得したlogsql.sqliteをWebでグラフィカルに見ることができるようにするものです。
    • Webフロントエンドとか言うんですかね?その辺の用語の定義が曖昧なもので…
  • こんな感じ。 f:id:Gen_IUS:20160321052045p:plain
  • Djangoとかで動いているようです。Djangoはあまり詳しくないので、そのあたりでも結構詰まりながら、試行錯誤してどうにか導入しました。
    • Node.jsといい、Djangoといい、バージョン周りの依存関係なんとかしてくれ

早速導入してみる

バージョン周り

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

実際に動かす

  • 起動コマンドを叩くと、migrateしてね的なことを言われました。
    • 言われるがまま、python manage.py migrateとしておきました。
    • 多分、環境が変わった時に叩く用のやつなのかな?

動いたと思ったら

  • ブラウザを起動して、ハニーポットのIP:8000にアクセスすると、グラフ等が表示されると思います。
    • 左側のメニューから、Connections, Downloadsを選択すると、エラーメッセージが表示されました。
      • nospacelessというタグがねえぞと言われているようです。
    • /opt/DionaeaFR/DionaeaFR/Templates/table.htmlから、nospacelessタグと、その終了タグをすべて消すと、うまくいきました。
      • 表示がおかしくなるかなと思いましたが、大丈夫そうです。
    • sedが好きな方は、sedを使うと楽だと思います。3個程度だったので、私は手で消しました。

感想的な

 UIがかっこいいので、それだけでも十分使う価値があるんじゃないかなと思います。Dionaeaはシミュレートするサービスが多いので、グラフィカルに見れるのは嬉しいです。ただ、DionaeaFRの動いているポートへのアクセスもDionaeaが記録してしまい、ログが自分のアクセスが埋まるというアクシデントが発生しているので、そのあたりの対処も今後していきたいです。

まだCentOS 6.5で消耗してるの?

利用していたVPSにデフォルトでCentOS 6.5が入っていたので、他のOSをインストールするのも面倒だという理由でそのまま使っていた。
自前でPython 2.7.11をビルドするなどして無理やり使っていたが、Dionaeaの導入がうまくいかず、記事もDebian系のものが多かったので乗り換えることにした。

というわけで、Ubuntuに乗り換えてcowrieとDionaea入れてハニーポットを運用してみている。
DionaeaFRはVPSのスペックがないのでVPSに入れずに、sqliteのファイルをローカルに保存して確認する形にしようかなと思っている。