🕌

セキュリティ・ネクストキャンプ2021 応募課題晒し

2022/05/04に公開

遅くなってすいませんすいません。去年のネクストキャンプの応募時に提出した課題を公開します。課題はしばらく変わっていなそうなので、どういったことを書けばいいのか参考になると思います。

課題: あなたに関する問い

あなたは今までどのようなことをやってきましたか.どのようなことができて,どのようなことが得意で,どのようなことに自信がありますか.
どのようなものを作りましたか.どのような情報を発信してきましたか.
どのようにしてそうしたことをやってきましたか.なぜ,そのようなことをやってきましたか.やってきてどう思いましたか.
参加できた場合,セキュリティ・ネクストキャンプにどのようなことを期待し,どのようなことをやってみたいですか.

ざっくり時系列で書いていきます。

主に調べた内容をそのまま実行していた頃について

小学生の頃はEeePCを使用していました。その頃はコンピューターに関する知識はあまりなく、プリインストールされていたWindows XPを使用していましたが、そのままではストレージやメモリの容量・性能不足で使い物になりませんでした。インターネットで改善方法を調べ、XP Embedded向けに提供されているEWF(ストレージへの書き込みをRAMにキャッシュする機能)をインストールしたり、nLite(Windowsのインストーラをカスタマイズするソフトウェア)を用いて不要なコンポーネントを削減したりして、軽量化していました。
ただ、安定して使用できるものではなく、データが消失したり、起動しなくなったりすることも頻繁にありました。データ復旧のためにKnoppixのLive CDを使用してからは、Windowsへの不満もありLinuxを使い始めました。
この頃はLinuxはサーバー用途であるというイメージが強かったため、CentOSなどのディストリビューションを試用していましたが、当時のCentOSのLinuxカーネルは2系で、ノートPCに搭載されているNICのドライバは自分でコンパイルする必要があるなど大変だったように記憶しています。UbuntuはGNOMEなどがスペックを必要とするため、軽量なPuppy LinuxやLinux Mintなども試用していた記憶があります。
いきなり全ての環境をLinuxに移行できたわけではなく、ゲームなどはWindowsでプレイしていました。プレイ中のゲームのメモリを書き換えることで新たな改造コードを探し、コミュニティと共有することもしていました。
また、CPUや電子回路の動作原理に興味があり、源内CAD支援コンテンツ などを参考にしながら源内CAD(論理回路設計支援ツール)で論理回路のシミュレーションをして、ゲーム感覚で楽しみながら理解を深めていました。

過去に作ったものについて

中学生の頃は、学校の都合により頻繁に変わる時間割を、LINE(アプリ)を用いてクラスで共有することをほぼ毎日行っていました。
学校では携帯電話の持ち込みは禁止されていたため、写真を撮影することはできず、キーボードで入力していましたが、入力を楽にしたいと考えました。そこで、教科をテンキー状に並べたWebページを作成し、JavaScriptでクリックイベントの発火時に、その教科名をtextareaに追記して、LINEの公開投稿画面にテキストが入力された状態で遷移するようにして、入力・共有を楽にしていました。この頃使用していた端末はiPod Touchで、何度か画面を破損させた際には、タッチパネルを購入して自分で交換して修理していました。
中学を卒業する頃には、DTIがMVNOとして提供するデータ通信専用回線と、基本料金が無料の050 IP電話サービスを親に契約してもらい、月500円のみ負担してもらって、Amazonで購入した5000円弱のAndroid端末を使用していました。

高校生になりXperia(Androidスマートフォン)を購入した際には、技術的興味から、公開されているrootkitを使用してroot権限を取得しました。
AndroidはLinuxカーネルを使用しているため、Android上でLinux環境を構築したいと思って調べてみたところ、ArchLinuxARMを実行する方法を見つけ、環境を構築しました。ArchLinux環境にchrootしてCUI環境を使用することと、CUI環境でVNCサーバーとXvfbを起動しておき、AndroidアプリのVNCビューアーからlocalhostに接続してGUI環境を使用することができました。Android上でのTeXのタイプセット、Emacsの起動、Mikutter(Twitterクライアント)からのツイート、Pidgin(マルチプロトコルIMクライアント)とpurple-lineプラグインでのLINEの使用にも成功しました。
また、Androidのタッチパネルのデバイスファイルに対して座標を書き込むことでタッチ操作をエミュレートして、スマートフォンのゲーム操作を自動化していました。
部活動では学生会で会計を担当していました。そこでは帳簿は先輩から代々受け継がれるエクセルファイル上で管理されており、VLOOKUPなどの関数を駆使して科目ごとの合計などを計算していたのですが、数式が入力されていた行数を入力データが超えそうになったとき、誰もその修正方法が分からない状況でした。
しかし、常々私は帳簿の計算の遅さにうんざりしており、またエクセルの関数を使用する、制約の多い(一種の)プログラミングに楽しさを見出し、1年目で仕事が少ないこともあって、こっそりリファクタリングを実施していました。そのため、何か問題が発生したときには、私の成果物を使用して業務を遂行することができました。
また、高校の授業用コンピューターはLinux上のVMでWindowsが起動していたのですが、起動中に仮想コンソールを切り替えてCtrl-Cなどを連打すると、起動シーケンスが中断されてシェルへアクセス可能になることがありました。ファイルへのアクセスも可能だったため、パスワードの設定されていたブートローダーの管理者パスワードのハッシュを入手するなどしていました。
高校在学中は、機種変更に伴ってLINEの全てのデータを移行したくなったり、突然LINEのデータが壊れたりすることが何度かありました。当時は全ての端末でroot権限を取得していたため、Androidの/dataディレクトリからLINEのSQLiteデータベースファイルを取り出し、バックアップしたり新しい端末に移行したりしていました。

メインのマシンでもArchLinuxを使用するようになってからは、ストレージなどはEeePCの頃ほど逼迫していませんでしたが、書き込みを別のパーティションに向けて、ルートパーティションをリードオンリーでマウントしたいと思うようになりました。ArchLinuxのLiveメディアで使用されている方法を調べると、systemd(init)が実行される前のinitramfsでスクリプトを実行していることが分かりました。そこで、リードオンリーなルートパーティションに、書き込みができるようにoverlayfsを重ねてからsystemdを起動するようなスクリプトを作成しました。そうすることにより、OSのパッケージマネージャーを使用してインストールしたファイルと、インストールしたソフトウェアが実行時に作成・変更したファイルを完全に分離することができるようになりました。これは便利だと思いQiitaに記事を書いて発信しましたが、ファイルが破損しやすかったり、カーネルのアップデート後のシャットダウンでカーネルパニックを起こしてしまったりする問題があり、特にカーネルのアップデート時に行われている処理について詳しくデバッグする必要があると感じています。

最近の活動について

最近では、PC用のキーボードを自作していました。KiCad(電子回路を設計するソフトウェア)で基板を設計して、基板データを業者に送信して発注し、メカニカルキースイッチやダイオード、AVRマイコンボード(ATmega32u4を搭載したもの)を半田付けすることでハードウェアを制作しました。また、QMK Firmware(自作キーボード用ファームウェア)で独自のキーマップを定義してマイコンに書き込むことで、USBキーボードとして動作するようにしました。親指はスペースバーを押す程度の役割しか担っていないと感じていたため、親指部分に装飾キー(Ctrl,Alt,Shiftなど)をまとめたキーボードを制作しました。また、QMK Firmwareのキー入力を処理する部分にC言語で独自の実装を追加して、PC不要でエニグマ(暗号機)をエミュレートできるキーボードも制作しました。I2C接続のLCDに入力と対応する文字を表示することに加え、キー部分にLEDを実装して、対応するキーを光らせることでエニグマらしさを演出しました。さらに、対応するキーをPCに対して出力することで、PCに入力する時点での暗号化も実現していました。

Dockerが好きなことと、ブラウザは信頼できないJavaScriptなどのコードを実行するためセキュリティ上の懸念があることから、ChromiumやFirefoxをDockerコンテナ内で実行することにも挑戦しています。ホストマシンのX11をコンテナ内に見せることで、直接ホスト上にウィンドウを表示させることも可能です。以前試したときには動画再生時に落ちてしまう問題がありましたが、いつのまにか解決していました。IMEが利用できるようにできれば、方法を発信しようと思っています。

ArchLinuxを普段から使用していますが、その日本語コミュニティは活発とは言えず、ArchWiki 日本語版も編集がほとんど行われていません。ArchWikiには様々なソフトウェアの有用な情報が蓄積されていて、目を通すだけでもかなり勉強になると感じます。また、個人的に英語の習得の必要性を感じています。このようなことを複合的に考えた結果、ArchWiki 日本語版を英語版から翻訳することで貢献することにしました。2020年4月からほぼ毎日少しずつですが継続しています(時々中断することもありますが)。翻訳にあたっては機械翻訳は極力使わず、文法自体に自信がない場合にのみ意味の確認のために使用する程度に留めています。技術的な文書であるため知らない単語は比較的少ないですが、適切な対訳を探すためにも単語やフレーズ単位で意味を調べたりしていて、翻訳を始める前よりも英語力の向上を感じています。
GitHub Pagesでブログを毎日書いていた時期もありましたが、毎日更新することに重点を置いたことで疲れてしまったこともあり、しばらく中断してしまっていました。今回の応募を機に更新を再開しました。

自信があること

今までにやってきたことを考えると、何らかの課題・問題に対して、それを解決に導くことが得意です。また、未知のシステムなどについて理解することや、そこに新しい技術や機能を添加しより良いものや自分が求めているものを作ることに長けており、一から同等の機能を持ったものを作ることにも自信があります。さらにチームのプロジェクトで多くみられる立場による価値観や要望の相違について、私は自分のスタンスを持ちつつ双方の意見や立場、ねらいを汲み取り、双方ができるだけ納得のいく案を提示、バランスを調整しながら作業を進めることを得意とします。

本当に必要とする要件を検討し、一部を満たすものを組み合わせることで比較的低コストで実現することも得意です。未知のことや、あまり一般的でないことに積極的に挑戦して、新しい経験や技術を習得しようと努力しています。むしろ、既知のことの繰り返しのみの日々を送ると、今の技術習得のチャンスを逃しているように感じてしまい逃げ出したくなってしまいます。何か選択や決断をするときには、2つ以上のメリットを検討してから決定することが多いです(今の自分へのメリット、他者へのメリット、将来の自分へのメリット等)。

あえて不得意なことを書くとすれば、答えのないことや評価軸の曖昧なことに取り組むのは苦手です。デザインを考えること、ビジネスモデルを考えること、新規サービスやプロジェクトのアイデアを出すことは他の人に任せられる方が、パフォーマンスがよくなることが多いです。(これがあまり自発的に何かを作ってこなかった理由でもあります。)

セキュリティ・ネクストキャンプに対する期待

今回のセキュリティ・ネクストキャンプではプログラミングがテーマとなっているため、参加できた場合、今後の仕事や趣味での開発に役立つ能力を身に付けられることを期待しています。TDDについては経験がありますが、モブプログラミングについては経験がないため、ぜひ挑戦したいです。そもそもチームでの開発の経験が少ないため、同年代の優秀な方や、講師の方との開発・交流を非常に楽しみしています。

課題: 課題への姿勢に関する問い

自身で何らかの技術的な疑問を設定し,その疑問を解決しようと取り組み,その過程を示すことで,自身の技術力や課題に取り組むやりかたを説明してください.
(疑問の例:実行ファイルはどのような構造になっているのだろう? lsコマンドは何をしているのだろう? pingコマンドを実行すると何が起きるんだろう? といったようなことです)
設定する疑問は何でも構いませんし,解決しなくても構いません.
解決できたかどうかではなく,いかに課題に取り組むかという点を評価します.

NTTフレッツのひかり電話では、ルーターに搭載されているSIPサーバー機能を使用することで、スマートフォンから固定電話の発着信ができます。しかし、自宅で使用しているNuroひかり電話では、SIPサーバーの機能が提供されていません。ただ、電話用のターミナルアダプタ(TA)と光回線終端装置(ONU)はLANケーブルで接続されているため、NICを2つ用意したPCでTAをエミュレートすることで同等の機能が実現できるのではないかと考えました。前提として、ONUとTAはプロバイダから貸与されているもので、分解やリバースエンジニアリングをすることは望ましくないと考えました。また、ONUに関しては管理画面からGPLによるファームウェア提供の項目がありますが、ISPが設定する項目についての情報が開示されるわけではないでしょうし、TAに関しては管理画面にアクセスすることもできないようで、ファームウェアが提供されるかも分かりませんでした。一応TAの型番"EV0524"で検索してみましたが、ソフトバンク製ということ以外にめぼしい情報はありませんでした。そこで、TAとONUの接続については容易に干渉することができるため、まずは接続を変更することによる動作の変化を確認しました。ONUにはTA用ポートとLAN用ポートが用意されており、TA用ポートにTAを接続すると正常に電話が機能するのに対し、LAN用ポートでは機能しませんでした。また、TA用ポートにPCを接続してみた所、LAN用ポートに接続したデバイスとのpingなどを用いた疎通確認が失敗する状況でした。PCをTA用ポートに直接接続しての検証ではあまり情報が得られないと判断して、NETGEARのアンマネージプラススイッチを購入して、ポートミラーリング機能を使用することで、TAとONUの通信をキャプチャすることにしました。使用したソフトはArchLinux上にインストールしたWiresharkです。NICを2枚用意してブリッジを構成することでも可能だとは思いましたが、すぐにNICが見当たらなかったことと、アンマネージプラススイッチを購入しておこうと思ったため購入することにしました。TAを起動すると、DHCP、ARP、Syslogなどのリクエストを投げているようでした。DHCPでは100.127.0.0/16のプライベートIPアドレスの範囲のネットワークを使用していました。Syslogでは、AS17676(ソフトバンクBB)の所有するグローバルIPアドレスに対してログを送信しているようでした。他には、NTP、TFTP、RADIUSの通信をしているようでした。その後、SIPの接続リクエストが、同じASに属するグローバルIPアドレスに対して送信されていました。リクエストは一度401 Unauthorizedと返答があった後、そのレスポンスに含まれるnonceを含んだリクエストを再度送信して、認証に成功していました。電話で通話中にはRTPパケットがやりとりされ、G.711 PCMUを使用しているようでした。構成としては、SIPを利用した一般的なIP電話であるようでした。また、RADIUSリクエストの送信先IPアドレスに、LAN側ネットワークからtracepathを実行してみると、solteria.netで終わるホスト名を持つホストからの返答がありました。ホスト名で検索してみると、ソフトバンクテレコムが提供していたIP-VPNサービスのようです。LAN側ネットワークとTA側ネットワークの分離を考えると、IP電話サービスについてはソフトバンクのIP-VPNを使用しているのではないかと思いました。

ここまで調査して、現在まで一旦調査を中断しています。FXOゲートウェイ(アナログ回線をVoIPで利用できるようにする)機能を持ったVoIPアダプターを使用した方が早そうだと思ったからですが、調べてみるとFXSゲートウェイ(VoIPをアナログ電話機で利用できるようにする)機能を持ったVoIPアダプターの方が多いようで、適切なデバイスを見つけるためにはもう少し調査が必要なようでした。(数が少なくて価格がネックというのも大きいです。)アナログ回線の呼制御を自分でなんとかする気力があれば、RaspberryPiのGPIOやオーディオインターフェースを使って自分で実装しようかとも思いましたが、TAとはいえ技術基準適合認定のない自作デバイスを接続していいのかどうかについて確認する必要がありそうです。

ソフトバンクの顧客数を考えると、配布するTAひとつひとつに認証情報を書き込むより、ONUを経由して毎回認証情報を配布する方が合理的かもしれません。RADIUSのパケットなどについてより詳しく検証すると、暗号化はされていそうですがSIPの認証情報が含まれているのではないかと思いました。上記の検証を実施したのはちょうど1年ほど前だったのですが、2020年末には使用しているONU(HG8045Q)の特権昇格の脆弱性が公開されました。ONU側の設定を確認することで、より詳しい情報を得られるかもしれないとも考えていましたが、2020年12月のアップデートにより脆弱性(管理者アカウント)は塞がれたようでした。

課題: 興味ある分野に関する問い

セキュリティ・ネクストキャンプの講義の一覧を見て,その中から興味のある講義を選び,その講義で扱うテーマに対して自分が考えること,興味,疑問,課題,自分なりの考察などを説明してください.
その分野について知識があるかどうかではなく,いかに興味や疑問を持ち,課題を考え,自分なりに調べて考察するかといった点を評価します.

7つある講義について見た所、全て興味があるものでした。

"TDD+モブプログラミング"については、前述の通り実務に役立ちそうな手法であり、他の人と一緒にプログラミングをした経験も少ないため、興味があります。"自分の知識をアウトプットしよう"と"インプット駆動型アイディアソン"について、これまで知識をインプットして実践してみるところまでは比較的多く経験があるかなと思っていますが、情報発信や知識の伝達についてはかなり少ないと思っていて、増やしていかないといけないと課題を感じていました。

"形式手法を知ろう"では、前から興味のあったCoqやIdrisに関する講義で、数学的な概念に支えられた型システムを理解することは、関数型プログラミングなどにも有用だと思うため、体験したいと思っています。CoqはOCamlで書かれていると知ったときから、(OCamlも非常に気になっている言語なので)ずっと触ろうと思っていたのですが、数学の基礎知識も不足しているように感じるため、大学で数学の科目を履修するなど準備を進めています。また、インターネット上にチュートリアルもあるようなので、実際に試して発信してみようと思っています。

"CanSatをはじめよう"では、普段の開発ではソフトウェアに閉じていることが多く、ハードウェアを用いるとしてもセンサーからのデータを取得するに留まり、アクチュエーターやハードウェアの制御はかなり経験が少ないため、その制御について考えるのは新鮮だと感じます。また、実際に移動させるとなると、設計時に想定しきれない様々なイレギュラーが発生すると思うので、それについていかに乗り越えられるように設計するか、ということも面白いと思います。100kin satのページの部品リストからリンクされているESP32-DevKitは、セキュアブートとフラッシュ暗号化周りの脆弱性(CVE-2019-17391,CVE-2019-15894)が見つかっているようで、新規設計非推奨となっていました。そのため、今回のユースケースでは影響はないかと思いましたが、ESP32-DevKitC-32Eにしておいた方がよいかもしれません。
早速秋葉原で購入して、Arduino IDEからサンプルプログラムの書き込みを行ってみましたが、あまりにあっさり完了したため驚きました。
また、サンプルスケッチも充実していて、iBeaconを受信してシリアルに出力することもサンプルのみでできてしまい、仕事ではRPiを使用したことがESP32でもできそうだと思いました。(蛇足: Nintendo Switchのゲーム(RFA)の反応が悪いことがあるのですが、都内の住宅街ではBluetoothは混雑しているようでした。)GUIよりCUIの方が好きなので、ESP-IDFを使った環境構築も試そうと思っています。
着地の検知は、加速度センサーの値が安定している(=静止している)ことを検知する方法が紹介されていましたが、ある程度の速度で落下している場合には3軸の加速度の合計が重力加速度を下回るのではないかと思いました。また、着地時の衝撃も検知できないかなと考えています。

"怪電波を解読せよ(RF Hack)"では、今回の中では一番セキュリティに近いことを扱っているため、個人的にはこれぞセキュリティキャンプ、というイメージがあります。講義紹介に記載されていたGitHubリポジトリを試してみた所、wavファイルの量子化のフォーマットがunsignedな8bitを要求されていることに気付かずハマっていました。READMEの最後の方に書いていたので、ドキュメントは最後まできっちり読む必要があると改めて感じました。(この間の応用情報でも同様の失敗をしていました。)試したことをブログに書いて発信しました。リポジトリにはライセンスについて記載がなかったため、今岡さんにTwitterで連絡し、フォークと改変の許可を取りました。公開されていたのは0/1のデジタル波形に変換したCSVを出力するところまでだったので、実際に文字に復号する部分まで作成して、講義当日に挑もうと思っています。

一番興味のある講義

特に興味があるものを1つ選ぶとすると、"低レベルGPUプログラミング"でしょうか。私自身はあまりAIの技術については詳しくないのですが、GPUの内部構造について学習することは、今後役立つことだと思っています。また、エクセル関数でのプログラミングと同様(と言ってしまうと失礼かもしれませんが)、特殊なアーキテクチャ上での低級プログラミングは、普段ない制約があるため楽しめることを期待しています。

Raspberry PiのGPUについて調べてみた所、Raspberry Pi4に搭載されているVC6はリファレンスが公開されていないようだったので、講義紹介にある「GPUの詳細なリファレンスが公開されている」という文面から推測すると、Raspberry Pi3などに搭載されているVC4を使用するのと推測しました。VC4のPythonライブラリのPyVideoCoreを使用してみた所、最新のLinuxカーネルでは依存ライブラリ(idein/rpi-vcsm)が使用できないことを発見したため、使用できるカーネルバージョンと他のissueなどの情報を集めて、GitHubでissueを作成しました。Linux5.4を使用することで、サンプルプログラムを実行することができました。ポラード・ロー素因数分解法をGPUで(CUDAですが)実装した論文や例があるようなので、それをVC4に移植することを試してみようかなと考えています。

課題: その他に関する問い

その他,アピールしたい点などあれば自由記述で回答してください.

コンピューターの範囲に限らず、ものづくり全般が好きで、ホームセンターで木材を購入して切断し、部屋のサイズに合った棚を組み立てることもあります。物理的なセキュリティにも興味があり、実家の玄関の鍵が脆弱なディスクシリンダー錠だったため、MIWA PRシリンダーを購入して自分で交換しました。コンピューターの範囲では、セキュアブートやdm-crypt、GPG、SELinux、802.1Xなどのセキュリティ技術にも興味があります。自分で署名したブートローダーでセキュアブートさせたり、GRUBとLUKSを使用して/bootを含むフルディスク暗号化をしたり、Raspberry Pi 2BをエアギャップコンピューターとしてGPGキーを作成しYubiKeyに入れて使用したり、LAN内にFreeRADIUSサーバーを構築してONUのWiFi設定をWPA2 Enterpriseにして自宅で使用したりしています。

今の私からのコメント

応募される皆さん、頑張ってください。期限のギリギリまで諦める必要はないですよ!!!!
(実際私は期限が延長されたことでかなり救われました。)

公開されている課題も参考になると思います。が、それをそのまま提出したら多分落ちると思います。
書くことが思いつかない人は今からでも面白いことをしてみましょう!どうしても今年は難しくて来年もチャンスがある人は、来年に向けて今からやってみましょう!!

Discussion