晴耕雨読

work in the field in fine weather and stay at home reading when it is wet

seccamp2018全国大会に参加

セキュリティキャンプ2018全国大会の集中開発コースで TLS 1.3 を実装したのでその話と、私の記憶がある限りの全ての出来事をここに書いていこうと思います。

応募課題

4/24にセキュリティキャンプ全国大会2018(以下seccamp)の課題内容が掲示されました。

とりあえずどんなゼミがあるのか一通り見たところ、集中開発コースのTLS1.3/暗号ゼミが一番面白そうだったのですが、全然内容がわからなくて応募しようかどうしようかと悩んでいたのですが、課題のところのコメントに「根気よく調べて学べば, 今『一見さん』でも『顔見知り』や『知り合い』にはすぐなれます. 」と書いてあって、根気よく調べて応募すればもしかしたら通過できるかもしれないし、ダメだったとしても自分の知識が増えるからやってみようと思い、とりあえず結城浩『暗号技術入門 第3版』を買って勉強しようというところからスタートしました(この時点では全くの初心者でした)。

大雑把に課題内容を言うと、(問1) TLS1.3の変更点・改善点の説明、(問2) SSL/TLSの脆弱性の説明、(問3) 基本的なトピックと発展的なトピックについてそれぞれ1つ選んで説明、(問4) 自己アピール、という内容でした。

初心者なので全部一から調べながら説明を書いていたので、最終的に応募用紙完成するまでに3週間かかってしまいました(僕が会った人に5時間で応募用紙作ってキャンプに来た方がいますので比べれば差は歴然かと)。

コメントにもありますが「ぜひ, 知らない物にチャレンジしていってほしいです.」と言うことで、リストの中から選択して説明する課題は自分の知らないことを選んで説明するのが、やる気を示すという意味でも良いと思います。 ちなみに私は基本的なトピックで 「ChaCha20/Poly1305」、発展的なトピックで「格子暗号」について説明しました。

TLSと格子暗号についての知見が広がったので、この時点で圧倒的成長💪💪💪

書類審査通過

メールで書類審査通過したことが伝えられました。下は喜びのツイートです。

この合格の知らせが来たのと同じタイミングで自分がGithub上に公開しているプログラムに脆弱性があると教えてくれたPull Reqを受け取りまして、すぐに修正しました。この小さな出来事によって、全く知らない人にセキュリティキャンプに来たきっかけを説明するときに「プログラミングが大好きでいろんなのをGithubで公開しているんだけど、脆弱性を教えてくれたPull Reqを受け取ってセキュリティについても勉強しないといけないなという気持ちになって、キャンプに来ました」のように自己紹介と共に説明できるので、とても役に立ちました。Pull Req投げてくれた人に感謝!

一応、参加者概要を載せると、応募数403で合格者数85で全体の倍率は4.74倍らしいです。 85人の中で高専から来たという人は7人でした。 一番下は12歳から一番上は22歳で、一番多い層は20歳21歳でした。

事前課題

TLS1.3のRFCを読みながら、TLS1.3のプロトコルを実装しました。 当時はまだドラフトのRFCでしたが2018年8月に正式に発行されましたので、そちらのリンクを参考資料として載せておきます。

https://tools.ietf.org/html/rfc8446

RFCは全部英語であまりゆっくり読んでいると時間がなくなってしまうので、Google翻訳使いながらささっと概要を理解して構造体の実装あたりから取り掛かりました。 構造体ができたら、それをソケットで送るためにバイト列変換する処理と、バイト列から構造体を構築する処理が必要だとわかったので、次にその辺の実装をしていました。 リストをバイト列にする方法がRFCにはっきりと書かれていなくて困っていたのですが、TLS1.3の通信をパケットキャプチャしたものがネットにあったので、TLS1.3対応の最新版のWireshark入れてどんな感じにバイト列に変換されているのか確認しながら進めていました。

期間の最初の方は何かと時間があったのですが、seccampに近づくにつれて学校の前期期末試験と学内の専攻科1年の研究発表会があり、なかなか思うように開発が進まなかった中で、TLS1.3対応の最新版のopensslを使ってハンドシェイクできるか確認して見たらエラーで失敗することに気づいたのがキャンプ数日前のことでした(フラグ)。

キャンプに向けての準備

ちなみにseccampには名刺を100枚くらい持っていった方がいいのですが、僕はキャンプ数日前になるまで名刺作るの忘れていて、発注する訳にもいかず、急いで家電量販店にいってラベル屋さん.comのマルチカード100枚を500円強で買って家で印刷しました。ここまではいいのですが、不幸にも自分の学科名の入力ミスに気づいたのが印刷し終わった後だったので、1枚1枚修正テープで消すなどの作業をしてました。名刺作りは計画的に…(聞いた話によると初回だけ無料で名刺100枚作って自宅に送ってくれるサービスがあるらしいので、そちらも調べておくといいです。)

キャンプの数日前は忙しすぎて数理の期末試験の存在を忘れて試験当日の10分前に気づくという失敗談もありますが、ここでは書きません😇


キャンプ Day1

開催場所はクロス・ウェーブ府中です。長野駅からは全席指定席の新幹線「かがやき」で大宮まで1時間、あとは埼京線で武蔵浦和駅まで行き、乗り換えで武蔵野線を使って北府中まで行くという乗り換えチャレンジに成功しました。

12:00〜12:30に受付をして昼食。同じ机に座った講師の @slankdev さんに高速なソフトウェアルータの話を聞き、セキュリティキャンプってすごい人の人口密度がやばいほど高いと改めて感じました。

全体講義では11班あり、各班に8人違うゼミの人たちが割り当てられました。同じ班の人と簡単に名刺交換をして、全体講義が始まりました。

Day1 のスケジュールは下の通りです。

1. 開会式

👏👏👏

2. 全体講義:セキュリティ基礎

失敗・ミスをする ~= セキュリティ的に良くない場合がある。ということで、次の質問を班で考えることになりました。

  • 失敗から学ぼうとする時にどんな阻害要因が考えられるか?
  • 阻害要因をどう阻害すればよいか?

考えてまとめたものを発表する時間になり、別の班では次のような発表がありました。

  • 失敗には他人の失敗と自分の失敗があり、他人の失敗は他人事のように感じたり情報入手できないために、失敗から学ぶことは難しい。その解決策として、失敗した情報をpublicに公開するか、それができなくても社内で公開すれば良いという結論になった。

  • 失敗を公表するデメリットは、責任で金を取られる、報復される、会社の価値が下がる、システムの内部がバレる、ということがある。なので失敗を匿名で公表する必要があるという結論になった。

  • 失敗を防ぐためにはわかりやすいシステム作りと、失敗を議論する場所が必要だという結論になった。

3. 特別公演(1) 自由なエンジニアとは何か

OSC(オープンソースカンファレンス)を10年以上続けて来た中での失敗した話や、OSCはオープンソースの文化祭みたいで楽しいので皆さんも参加者・出展者として参加してください!というお話でした。

4. 特別公演(2) ハッカーは法律を破るのか

どのような行為が犯罪行為にあたり、どこまでが大丈夫なのかという話を身近なゲームやスマホの話題を使いながらわかりやすく説明してくれました。終盤では広告の代わりにビットコインのマイニングをやる行為は犯罪行為なのかについてのお話もあり、最近起きた事件なので興味深く聞くことができました。

5. LT大会

夕食後にLT大会が行われました。僕が見たもので面白かったのは「Nintendo Wiiの正しい遊び方」というやつで、どんな話かな〜と聞いていたら唐突にWiiの中のLinuxに入っていて、フィボナッチ数列を求める速度をMacBookと比較するという、まさにWiiの正しい遊び方だなと思ってしまいました(笑)。

もう一つは「CODEGOLF」というタイトルでFizzbuzzをcodegolfする話です。Fizzbuzzをいろんな言語でCodegolfしていく過程が見れたのと、最後にgs2というcodegolf専用言語で1byte「f」でFizzbuzzするところを見て大団円で終わりました。

6. グループワーク

今年のグループワークは講師やチューター、スポンサーの人たちの話を聞いて、セキュリティキャンプ終了後にどんなことをしたいかという未来について、考えをまとめて最終日に提出するものでした。

僕がお話を聞いた順に書いていきます。内容に間違いがあったらごめんなさい。

1人目 チューター: 友達がチーターであったこと、アセンブリを解析してパスワードを取ることをお願いされたことなどからセキュリティに興味を持ったとのこと。 チュータとして参加したのは講義が聞けるからと、他のスタッフと交流できるから。 普段はgdbの改造をしたりしている。

2人目 チューター: プログラミングやOS自作をしている。 高専の先生がいろんなところに連れていく or 紹介するので、色々参加した。 ICTSC(ICTトラブルシューティングコンテスト)、情報危機管理コンテスト、SecHack、seccampなど。 チューターとして参加したのは講義などを聞いて勉強したいから。

3人目 講師: NTT社員ではソリューション系の仕事をしている。 OJTでLinuxを勉強し、セキュリティの仕事をしたこともある。今はプログラムの仕事をしている。 おそらく(というか絶対)Linuxのプロ。 @tex2e という文字列をみて LaTeX の話で少し盛り上がったのでちょっと嬉しい

4人目 講師: 普段はハードウェアや下のレイヤーを使っている。 FPGAを破る実習をキャンプで行ったとのこと。 仕事としてはFPGAの開発で、コピー機やカーナビ、今は大学向けの計測器を開発している。

5人目 講師: NTT社員でセキュアプラットフォーム研究所の主任研究員。 セキュリティのきっかけは、P2Pファイル交換で友達が無料でCDの内容を持っていたのと、友達がファミコンのエミュレータを解析したりしていて、さらに某サイトに exploit コードが載っているのを見たりして、この世界に入ったとのこと。 仕事では研究員として、攻撃コードを解析したり、論文を出したりしている。

6人目 講師: Cybozu Labsの方。 仕事ではストレージ、データベース、バックアップシステム、クラウド、インフラなどなど。 データベースについては、良いアルゴリズムができたので、英語で論文書いたり国内のワークショップや国際学会で発表する予定とのこと。 OS自作の人が一定数いるように、データベース自作ができる人も増やしたい。 今後、研究ではデータベースの分散処理をやりたい。

7人目 チューター: JSやWebアプリからXSSを学び、セキュリティに興味を持った。 seccamp2014年卒業、今は大学生。 正規表現で(悪意のあるバイナリとの)パターンマッチングなど。

1日目で色々な人に話を聞きましたが、体感としてはチューターよりも講師や企業の人に話を聞いた方が色々面白いことが聞けると思うので積極的に、どんな仕事しているの?みたいな感じでどんどんいけたのがよかったです。

グループワークは22:00終了で、寝たのは23:00くらいでした。おやすみ!


キャンプ Day2

Day2 のスケジュールは下の通りです。

1. TLS 1.3/暗号ゼミ

8:30〜22:00まで、食事と休憩を挟みながら集中開発コースのTLS 1.3/暗号ゼミで実装・デバッグを行っていました。

最初の方では ChaCha20/Poly1305 の方で問題があったので、相方の @ykm_kn さんが実装している間に僕は chacha20 のテストベクタを使ってunittestを書いたりしていました。

緑川先生 @elliptic_shiho からは(良い意味で)変な人になろうという話や、エラーは怖くない(失敗することがわかっているエラーは放置してもよい)、デバッグ情報は次のようにするとわかりやすいよ、という話もありました。

  • [+] 〜 でデバッグ内容を表示する
  • [-] 〜 でエラーの内容を表示する
  • [*] 〜 で実行中のinfoを表示する

あとは、スポンサーの企業の人が見学に来まして、あまりお話できなかったのですが、セキュリティで仕事している人たちがお盆の期間を使って見学するのをみて、お盆とか関係なくみんなEnjoyしているのだと感じました。

Day2終了時点では openssl とのハンドシェイクができず、どうやらEncryptedExtensionメッセージを送っていないことが原因だとわかり、部屋に戻っても作業をしてとりあえず証明書をCertificateメッセージで送ることができるまでになりました。23:00を回ったので、シャワー浴びておやすみ!


キャンプ Day3

Day3 のスケジュールは下の通りです。

1. TLS 1.3/暗号ゼミ

ただひたすらにデバッグしてました。現状ではオレオレ証明書をCertificateメッセージで送るところはできたけど、CertificateVerifyで失敗するので、先生に聞いてみたら古い署名のアルゴリズムを使ってエラーになっているとのことだったので、別の署名に変えたところ、その部分のエラーはなくなりました。

次のエラーはMACエラー(これがこのゼミの中で一番厄介な問題だった)で、MACを計算するまでの全てのフローを見直してopensslやRFCと間違いがないか、確認する作業が続きました。

個人的に大変だったのは sequence number と IV の XOR をとって nonce にするという処理が必要であることでした。具体的には下のことがありました。

  • 作ってもらったChaCha20の振る舞いを変えずに
    • ChaCha20 では IV を int型の配列で管理していて、sequence number はint型で、xorとるにはどちらもbyte列する必要がある点
    • 求めた nonce を ChaCha20 に渡すときに再び int型の配列にする必要がある点
  • sequence number がインクリメントされるタイミング(クライアントとサーバが別々で値を持っているのか否か)
  • 複数のメッセージ(例えば ChangeCipherSpec + Finished)が同時に送られてくるときに対応しないといけない点

sequence number がインクリメントされることはRFCには書いてあるのですが、ハンドシェイク時にはクライアントとサーバが別々の番号を持っていて、ハンドシェイクが終了すると seq_number = 0 にして、今度はクライアントとサーバが共通の番号を持つようになるあたりは、RFCに書かれていないので、まぁ大変でしたよデバッグが。(2018/8/21訂正:共通の番号ではなく、ハンドシェイク後も別々の番号を使っていることを確認しました。ここに訂正します。)

お昼の時にチューターの @lcst_topevx さんに TLS1.3 について説明する機会があって、振り返ってみると全体発表するための自分の考えを整理する機会になったので、話を聞いてくださって感謝という気持ちです。ておくれ談義も見ていて面白かったです(笑)

Day3終了時点では openssl とのハンドシェイクは、サーバが Finished を送るあたりまでは良さそうで、クライアントがApplication Dataを送るのは問題ないところまでできたのですが、サーバ側からクライアントにApplication Dataを送ると mac エラー or unexpected message で失敗するという状況でした。

確率的に失敗する MAC エラーの謎もあり、このままではやばいのではないかという焦りの色が見え始めていました (AEADで求めたTagが1byteだけずれてるのおかしくない?みたいなこともありました)。

2. 会員企業のお仕事紹介

スポンサー企業のセキュリティ室から自社での仕事の様子などを25分x2で説明してもらう時間です。

事前のアンケートで答えたところでお話を聞けたのでよかったです。

1社目はNTTDATA先端技術のお話を聞きました。セキュリティの仕事としては、脆弱性ハンドリング、攻撃を遮断するサービス、セキュリティアナリストがDockerで環境構築してPoCを行う、などがあります。「Snort」というシグネチャを検知するやつを使っているそうです。私も始めて聞いたのですが、どうやらルールを書くことで不正侵入を検知するらしく、例えば method: "PUT", url: ".jsp/", content: "<%" というルールに当てはまるやつは不正侵入に分類するといった具合です。脆弱性診断員はペネトレーションテストをファイアウォールの外や内から行うことをしているそうです。

2社目はLineでした。Lineのセキュリティ室ではアカウントの乗っ取り/Abusing対策やR&Dを行っているそうです。 Lineでは通信の暗号化に「Legy encryption」というものを使っているのですが、話を聞く限り、実はこれは限りなくTLS1.3に近いものでした。さらに、TLS1.3では複数の鍵共有方式をサポートしていますが、Legy encryptionでは楕円曲線を使った鍵共有(ECDHE)だけを使うことで決め打ちにして通信量を減らしたり、サーバの公開鍵をLineに埋め込むことで、ハンドシェイクにかかるコストを減らして高速化しているとのことでした。 キーワードだけ上げると次の通りです。

  • Legy Encryption (Line Event Gateway Encryption)
  • Litter Sealing
  • Group talk EE2E (End-to-end Encryption)

メッセージ暗号化機能「Letter Sealing」では端末がそれぞれ通信をする相手毎に秘密鍵と公開鍵を持っているので、Lineサーバはユーザのメッセージを読むことは出来ないよ、というものです。しかしLineで送信するメッセージは全てLineサーバを通過するため、鍵交換した相手が本当に相手の端末なのか確認する方法がないから、論理的には中間者攻撃が成立する、ということも仰っていました。強調しておきますが、Lineは中間者攻撃で相手を偽るといったことをしていないそうです。もし真実を知りたい場合はLineに入社するしかないでしょう(笑)

3. グループワーク(2)

本当はいろんな人にインタビューする時間なのですが、TLS1.3/暗号ゼミの実装の進捗がよろしくないこともあり、 @ykm_kn さんと @6Lgug さんの3人でTLS1.3についてお話していました。 自分たちのところの実装が上手くいってないんだよね〜みたいな話とか、先ほどのLineの企業説明でのLegy EncryptionはまさにTLS1.3だったよ、みたいな話をしてました。

とりあえず残り数分でインタビューもしたので、その内容を書きます。内容に間違いがあったらごめんなさい。

8人目 スポンサー企業の人: 富士通でスパコン運用している人。 セキュリティに関して言えば、サーバの脆弱性にpatch当てたり、その情報をお客様に知らせたりしている。 並列計算は難しいというお客さんのためにプログラムを書いたりしている。 CPUを9割以上使っていないとお知らせ(兼営業)するみたいなことはしていなかった(元ネタは高専のI先生)。 セキュリティの業界にいるきっかけは、会社のコミュニティでのインシデント情報の共有などから。

9人目 スポンサー企業の人: 三菱の総合研究所のシンクタンクやっている人。 国のガイドラインや政策に対するサイバーセキュリティの観点からの助言をしている。

4. ホームルーム

ホームルームは選択コースの人が講師の人に質問する時間を取るためのものらしいので、集中開発コースはあまり関係ないので、とりあえず部屋に戻ってTLS1.3の実装を進めていました。 この段階では、ハンドシェイクが成功しても、クライアントからサーバにデータを送るときは成功するのに、サーバから送るときは失敗するという状況でした。

明日発表で、とりあえず動くものが必要なので、クライアントからサーバにデータ送るだけのものを書いて寝ました。 24:00回ってからコミットしたので、遅くまで作業していたのがバレるかなと思ってました(そしてバレました)。


キャンプ Day4

Day4 のスケジュールは下の通りです。

1. TLS 1.3/暗号ゼミ

緑川先生のデバッグもあり(圧倒的感謝!)、原因は NewSessionTicket を送っていないか、Application Data の送り方が間違っているというところまでわかってきました。 相方の @ykm_kn さんも chacha20poly1305 のバグを見つけ、MACエラーが出る確率がすごく小さくなる神コミットにより、作業速度は大幅に改善していきました。

とりあえず中身を適当に与えた NewSessionTicket を送り、さらにApplication Dataを送るプロセスを調べたところ、content + type + padding と送るところで type に handshake の 0x16 を入れたまま、アプリケーションデータとして送っていたことが発覚!。これを直したところ、ハンドシェイク後にApplication Dataが正しく送受信され、動いた〜〜〜🎉🎉🎉〜〜〜!という気分でした。

あとは sequence number の修正や、リファクタリングなどを行ったり、HTTPサーバのような機能を加えることなどを行いました。

TLS1.3対応の最新版のcurlをインストールして、実際に https://localhost にアクセスしてちゃんと html を取って来ることを確認し、Wiresharkでも暗号化されていることを確認した時には、肩の荷が下りた気分でした。

昼食後、他のゼミよりも遅れてスライドの作成を開始し、16:00〜のゼミ内の発表では curl を使って TLS1.3 で通信する DEMO を行うことができたのでよかったです。

1.1. 夕食

最後の晩餐です。同じ机にゼミ内の発表を聞いてくださったゲヒルン株式会社の代表取締役とTLS1.3の実装についての話とかしました。一番大変だったことは?と聞かれ、RFCではっきりと書かれていない部分を実装するのが大変だったと答えると、お行儀の悪いプロトコルが世界のシェアを持っているとお行儀の悪いプロトコルに合わせないといけないから大変、みたいな話をしました。あとは H2O というHTTPサーバを紹介してもらったり、名刺のところに PGP のフィンガープリント?みたいなのがあって面白いなと思いました。多分次に名刺作る時に参考にさせていただきます🙇

2. 会員企業のお仕事紹介

Day3 に続いて Day4 にも会員企業のお仕事紹介の時間が25分x2でありました。

3社目はパナソニックでした。PSIRT(Product Security Incident Response Team)の取り組みや日常について説明がありました。パナソニック製品の出荷前にハッキングして穴を見つけることをしたり、セキュリティ技術の開発や、脆弱性報告窓口などを取り組みとして行っているそうです。 流れとしては下のような感じです。

  1. 脅威分析
  2. セキュリティ設計
  3. セキュリティ診断
  4. インシデント対応

初心者なので始めて聞いたのですが、組み込み系ではUART(Universal Asynchronous Receiver Transmitter)を使ってシリアル通信を取り出して、パスワードなどの情報を得る方法があるらしく、それに対する取り組みとか、 あとはネットワークに繋がっている電子機器は全てセキュリティで守らないといけないので、仕事はいっぱいあるよ〜みたいな話だったと思います。

4社目はサイボウズでした。サイボウズではツールと制度と風土からセキュリティを上げていこうという理念があるようです。インシデント管理をして、インシデントの深刻度をしっかり決めておかないと、システムを止める必要があるのか否か判断できなくなるというお話が勉強になりました。インシデント対応では準備が大切で、事前にお客さんとセキュリティについてあるべき姿に共感してもらうことが大事と言っていました。これをしないと、セキュリティチームとお客さんとの間に温度差が生まれてしまうよ、みたいな話でした。他にも具体的な例を上げて説明していましたが、秘密事項なので書けません。

3. グループワーク(3)

ノートパソコンを持って、最終日に提出する「セキュリティ・キャンプ修了後に取り組むこと」について文章をまとめていました。 内容は下のような感じです。

少なくとも2項目以上記入する。セキュリティ・キャンプ修了後に:

  • 「個人として」取り組むこと
  • 「セキュリティ・キャンプメンバー」と取り組むこと
  • 「同じ興味を持つ仲間」と取り組むこと
  • 「セキュリティ・キャンプメンバーの枠を超えて」と取り組むこと

3.1. プレゼントタイム

スケジュールには書いてませんが、毎年恒例のプレゼントがありました。 去年は年齢の若い順でやったために大ブーイングが起きたらしいですが、今年はじゃんけんで、右側先頭の人(私もその一人)が班の代表としてじゃんけんをして勝てば、買った順にプレゼントを選ぶことができるというルールでした。 うちの班は1回目2回目はあいこでダメでしたが、3回目に勝てたので、全体としては真ん中あたりで取ることに成功しました。責任重大でした…

4. ホームルーム

集中開発コースの他の講師の方に、欲しいもの取れた?と聞かれ、暗号ゼミなので暗号に少し関連があるブロックチェーンのやつ取れたので満足です、と答えました。満足したので寝ます。おやすみ!

と、寝る前に荷物の自宅発送の手続きをしました。seccampではいろんなものを貰うので、スーツケースを持って来ていない私にとっては手で運んで持って帰るのは辛すぎるので、荷物まとめた袋ごとダンボールに詰め込んで発送してもらいました。着払いで1300円くらいかかりました。おそらく2kg以上あったのだと思います。


キャンプ Day5

Day5 のスケジュールは下の通りです。

1. グループワーク(4)

グループワークの課題を提出。提出は Google Form だったので、メール送るよりかは簡単にできました。 提出された中から良いものを紹介するコーナでは「変態になる」「CPUと仲良くなりたいのでとりあえず自作してみる」「ELF完全に理解したい」「刑法の本を1冊読み終えたい」などの個性的な内容があり、みんないろんなこと考えているんだなと思いました。僕も「XXX(技術名)と仲良くなりたいのでとりあえず自作してみる」構文を積極的に使っていきたいです😎

2. 講義の成果報告

TLS1.3/暗号ゼミも全体発表をしました。

3. 閉会式

👏👏👏


まとめ

振り返ってみると楽しくて短い5日間でした。また会えるかわかりませんが、チューターとして、CTFプレイヤーとして、イベントの参加者・出展側・主催者として、またどこかで必ず会いたいと思いました。でも、プロにならないと会えないので、もっとプロになりたいと強く思いました💪

とても刺激的な5日間でした。全ての関係者に感謝しています!ありがとうございました!