でるたのーと

初めに言葉があった


GCEインスタンスに LTE回線で ssh する

自然気胸で絶賛入院中なのですが、あいぽんの 20GB のプランを契約していることもあり、ここ 2, 3日は LTE回線で生命線をつないでおります。昨日まで肺に管がぶっささっててくっそ痛かったです。でも今日中には退院するのでご心配なく。



で、まぁ暇なので GCEインスタンスに入って pwn の練習とかしてたんですけど、まぁ切れる切れる。

packet_write_wait: Connection to 99.99.99.99 port 22: Broken pipe


きゃーまるで僕の肺のような脆さでぶちぶち切れていきますね! 素敵!

退院間際に直してもあまりうまみがありませんが、これではこれから先、お外で優雅な sshライフが送ることができません。この機会にどうにかしましょう。つかこうでもしないと 20GB + 繰り越し 10GB ぐらい余ってるパケットを消費しきれないんですよぅ。

解決策をバーンと

$ gcloud compute ssh username@instance -- -o "ServerAliveInterval 60"

です。ググったら出てきました。やったね☆



ちょ、ちょまーてよー。なんでこれでうまくいくんでしょう。

原因は何だ

そもそもこの問題は iPhoneテザリングをしたときにしか起こりません。Wimax回線ではこんなことにはなりませんでした。つかそもそも、GCEインスタンスはデフォルトで以下のような SSHD の設定を持っているはずです。

/etc/ssh/sshd_config:

# Google Compute Engine times out connections after 10 minutes of inactivity.
# Keep alive ssh connections by sending a packet every 2 minutes.
ClientAliveInterval 120

Google Compute Engine は 10分間何もされなかったらコネクションをタイムアウトします。
以下の設定でヌルパケットを 2分毎に送り、ssh のコネクションを維持します (意訳)。

f:id:deltatan:20180117194515p:plain

あ゙あ゙ん?

え、あの、ClientAliveInterval 120 だけじゃだめだったじゃないですか! どうしたクライアントアライブインターバル ワンハンドゥレッドゥゥゥゥ!

叫んでもどうにもならんので、このクライアンry のマニュアルを man sshd_config から見てみましょう。

ClientAliveInterval
Sets a timeout interval in seconds after which if no data has been received from the client, sshd(8) will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client.

ClientAliveInterval
タイムアウトのインターバルを秒で定め、その秒数過ぎてもクライアントからデータが送信されない場合は、sshd(8) は暗号化されたチャンネルを通し、クライアントからのレスポンスを要求するメッセージを送信する。デフォルト値は 0 で、これはメッセージがクライアントに送信されることがないことを示している。

まぁここから推測されるのは、LTE回線を使うことによって、クライアントからレスポンスが送信されなくなるっぽい、ということでしょうか。

sshd のログも見ておきましょう。

Jan 17 20:37:35 ctf sshd[1989]: Timeout, client not responding.


非常にこれが原因っぽい

なんで僕の Mac がこんな不感野郎になってしまっているのか。その原因は、ドコモの LTE回線が (他のキャリアもだと思うけど) キャリアグレードNAT を使っていること。そして NATテーブルがクリアされるまでの時間が短いことにあります。

試しにさっきの部分を ClientAliveInterval 60 に変更してサービスを再起動すると、接続が切断されなくなります。120秒だと長すぎて、変換エントリが削除された後にパケットがクライアントに送信されてたんでしょうね。そりゃ見つからんわ。

結論

というわけで、

  1. ServerAliveInterval 60 をクライアント側に設定する
  2. ClientAliveInterval 60 をサーバー側に設定する

という 2つの解決方法を見つけたわけですが、個人的に GCEインスタンスで使う分には後者の方がいいと思います。いちいち前者の設定を sshコマンドで渡すのも面倒ですし、静的IP を振っていなかった場合には、configファイルで指定するのもままなりません (HostName が変わるので)。まぁ起動しているインスタンスに静的IP を振るのは無料ですが、僕の場合けちってプリエンプティブルにしているので、停止する度に課金されてしまうのですね。

...誰かお金くれたらこんなみみっちいことする必要もなくなるのになぁ。

2017年の振り返りと 2018年の抱負

今の今までふざけ倒した記事ばかり書いてきましたが、大晦日ぐらいまじめな記事でも書こうかと思います笑

2017年、いろいろありました。

セキュリティ・キャンプに参加したり

deltatan.hatenablog.com

情報処理安全確保支援士試験に合格したり

deltatan.hatenablog.com


他にも Haskell でのバイト、CTF への参加、各種勉強会への参加など、自分なりに努力をしてきたつもりです。

いきなり話が飛びますが、僕は昔から魔法使いになりたかったんですね。ほら、アニメとかに出てくるじゃないですか。魔法を使って、問題を解決して、楽しそうな日常を生きる人たち。

もちろん、現実の世界は魔法が存在するようなファンシーなものではありませんし、僕の目にはクソったれに見えます。残業と薄給に耐え続ける社会人、電車の列に割り込んでくる人たち、こいつらは何のために生きているんだろう、とか。

...いや鬱とかじゃないですよ?w 友達と遊んだりするのはまぁ楽しいです。でも、それは誰でもできる普通のこと、本当に普通のことです。魔法のまの文字もありません。

じゃどうしよう、俺は何をして生きていこう、そんなことを考えていた時期に出会ったのが、BLOODY MONDAY とか電脳コイルみたいな、サイバーパンク的なドラマ・アニメです。現実とコンピュータという想像の世界を行き来しつつ、自分の思うままに生きるハッカーという人種を見て、「あぁ、魔法使いみたいだな」と純粋に思いました。

そしてそういうものが積もり積もって、文系ながら情報系の学部に進学するという、多少イレギュラーな選択肢を取ることになりました。

でもまぁ、
あの、
現実はそんなに甘くもなく、
大学入学からずっと、周りのすごい人たちにぼっこぼこにされ続けています笑

ここで「スーパーハカー(笑)としてマルウェアばんばん作りまくって、世の中のブラック企業をぶっつぶしています」とか言えたらかっこよかったんですけどねー! しかも文系なので、論理的思考の塊みたいな、バリバリ理系やってる人にはそりゃなかなか勝てないですよね (むしろ数学とか苦手だった)。

そこでさっきの「いろいろ努力してきたよー」の話に戻るんですけど、その過程でいろいろすごい人たちに出会うわけです。そしていつも負け続けるのですね。努力しているはずなのに勝てない。多分、心のどこかで思ってたんでしょう。「もうこれでいいか」と。「今の時代、プログラマは引く手数多だし、俺セキュキャンに参加したんだぜ? すごくね? もう十分だろ」と。

でも、これはそれこそ、自分が嫌悪していたクソったれな生き方そのものです。何のために生きているのか分からない。
つまるところ、自分はすごい人たちの魔法に憧れながらも、それを身につける努力を怠り、勝手に諦めていたわけですね。

どんなに勝てなくても、どんなにボコボコにされたって、それは夢を諦める理由にはなりません。だから、来年こそは、こんなふざけた態度をぶっとばしてやります。自分にはできると信じて、ちゃんと理解して、自分の言葉で魔法を語れるようになろうと思います。何が何でもやってやります。だってもう決めたんだから。

なのでとりあえず、2018年は

  • ctftime で予告される参加できる CTF には全て参加する

という目標を立てました。大学生活も残り 1年ですが、精一杯楽しみつつハッカーになれたらいいなと思っています。2018年もがんばるぞい!

f:id:deltatan:20171231175827p:plain

情報処理安全確保支援士試験に合格した

受かってるかなー、どうかなー、と思いつつ発表を見てみると受かってたので、この資格のこととか勉強方法とかをさらっと書いておこうと思います。


f:id:deltatan:20171221123620j:plain:w300



そもそも情報処理安全確保支援士試験とは

情報処理安全確保支援士試験は、情報セキュリティスペシャリスト試験の後継の試験です。他の高度情報処理技術者試験とは別枠になってしまいましたが、一応スキルレベル4 と同等の試験と見なされていて、試験内容自体も情報セキュリティスペシャリスト時代から変わっていません。科目もおなじみの、

  • 午前I試験
  • 午前II試験
  • 午後I試験
  • 午後II試験

という内容になっています。僕は応用情報を 1年前に取っていたので午前I試験が免除され、悠々と試験会場に向かうことができました。

ちなみに試験を申しこんだときはコミケに参加するために東京にいたので、応用情報の合格番号が分からず詰みかけました。が、影白君の情報提供により難を逃れました。みんな影白君をあがめましょう。


さて、まぁ情報処理安全確保支援士試験って登録料をぶんどるだけの情報セキュリティスペシャリスト試験なんじゃないのって思われる方もいると思いますが、ぶっちゃけその通りだと思います

ただ、登録しないと試験に受かったことを名乗ることができないとかそういう訳ではありません。今まで通り、情報セキュリティスペシャリストとか、情報処理安全確保支援士試験合格者という形で名刺や履歴書に書くことが可能です*1

というか、登録していない情報処理安全確保支援士試験合格者が「情報処理安全確保支援士、だぜ☆」と名乗るのがだめ、というだけであって、資格名をどう表現するのかは個人の裁量で決定していいみたいです。最悪、就活の際にイキりせきゅってぃうんこフレンズ支援士とか履歴書に書いても、IPA から怒られることはありません。間違いなく落とされるとは思いますが

あと、情報処理安全確保支援士試験の合格者は、情報処理安全確保支援士への登録の期限等はありません*2。しかし、情報セキュリティスペシャリスト試験やテクニカルエンジニア試験の合格者は、注意した方がいいです。制度の経過措置期間は 2年間で、来年の 8月 19日までに申請しなかった場合、情報処理安全確保支援士への登録資格を失います。もしもその後に情報処理安全確保支援士になる必要が出てきた場合、地獄の再受験です。

特に社会に出て仕事をしている方は、インシデントや残業に追われつつそれができるかどうか、よくよく考えましょう。

f:id:deltatan:20171221122605j:plain:w300

勉強方法

時間的には、1ヶ月程前から 1日 3-4時間ほどやっていたので、トータルで 90-120時間ぐらいです。試験は基本的に暗記ゲーなので、エビングハウス忘却曲線を意識して必ず 2日前までの復習をやっていました。

使った教材は、午前は 情報処理安全確保支援士 過去問道場 を 10年分、午後は iTEC が出している

の 2017年版と過去問をひたすら解くことで対策しました。

これだけで十分受かります。たっかい授業料を払って講習を受ける必要なんかありません (そもそも資格を取ることを目的にするのではなく、勉強から得られるものを考えるべき)。

注意点としては、

  • 憶測で物事を確定しない。必要な部分はできるだけ緻密に読みこみ、正しい根拠を見つける
  • 間違えた部分は、復習するときに自分の頭で考えながら解き直す

ということです。これは理解の鉄則です。この辺を適当にしているとまず受かりません。

また、ちょっと考えて気づいたのですが、別に全ての分野を網羅して勉強する必要もありません。

iTEC の参考書では、午後問を以下のように分類していました:

  1. 認証とアクセスコントロール
  2. PKI
  3. 時刻認証
  4. VPN
  5. ファイアウォール・IDS・IPS・UTM
  6. サーバセキュリティ
  7. 電子メールのセキュリティ
  8. ICカード
  9. セキュアプログラミング
  10. 物理的セキュリティ対策
  11. ログ
  12. インシデント対応
  13. リモートアクセス環境

例えば山を張って 13題中 10題しか勉強しない! と決めたとき、試験では

  • 午後I の選択問題 3題中 2題を選択する
  • 午後II の選択問題 2題中 1題を選択する

ため、

  • この 13題から 10題を適当に選んで、午後I の選択問題 3題中 2題以上が 10題の中から選ばれ、
  • かつ 午後II の選択問題 2題中 1題以上が 10題の中から選ばれる

場合、試験には何の影響もないことになります。だって山を張った 10題の中に、回答する問題全てが含まれているんだから。

  • 前者は 出題の 13C3 通りから (1) 3題全てが勉強したものではないという上条当麻的なケース (2) 3題の内、1題しか勉強した 10題に含まれていないケース を引けばいい。13C3 - (3C3 * 10C0 + 3C2 * 10C1) = 255通り。この確率は 255/13C3
  • 後者は 出題の 13C2 通りから (1) 2題のどちらも勉強したものではないという上条当麻的なケース を引けばいい。13C2 - 2C2 * 10C0 = 77通り。この確率は 77/13C2

前者 * 後者 * 100 = 88% ぐらいになります。多分。間違ってたら教えてください。

なので、ですよ。別に 3題ぐらい削ってもよっぽどの不幸体質でない限り、勉強した分野の出題を解くことができます。僕は時刻認証、ICカード、物理的セキュリティ対策を切りました。これらの分野はそもそも出題される確率が低く、案の定全く問題になりませんでした。切るところは切って、時間を有意義に使いましょう。

最後に

というわけで、すべりこみで申しこんだ割にはなんか簡単に受かってしまったという印象です。もちろん、これに満足するつもりはありませんが、就活に使えるカードが増えたのは素直に嬉しいです。資格に名前負けしないよう、これからもがんばっていこうと思いました。まる。

3DS でハローワールド

さて、前回の記事で我々はユーザーがいじくり回せる自由な環境を手に入れたわけですが...

deltatan.hatenablog.com

まぁ、次はハローワールドするのが妥当かと。そりゃ作れるものなら最初からドラクエみたいなのを作りたかったよ。でも技術力皆無の僕にはこれが精一杯でして。許して。

というわけで、この記事では

  1. Homebrew Launcher からハローワールドする
  2. タイトル (アプリ) からハローワールドする

という 2つのやり方でハローワールドしたいと思います。ちなみに最初から完全理解しようとすると情報量が多すぎてハゲるので、最初はざっくり理解するのがいいかと思います。

では、僕の髪の毛と貴重な就活の時間を犠牲にした成果をお届けします。いやほんと 12月にもなって何をやってるんだろう... べっ、べつに「この記事を見た任天堂の採用担当から連絡がくる」みたいな展開、期待してないんだからねっ!

環境構築

前回の記事にも書いたように、現行の 3DS は CPU に ARM11 を採用しています。まず、ARM11 向けにクロスコンパイルできるコンパイラが必要になりますよね。こういったコンパイラや必要なツールをまとめたツールチェインとして 、devkitARM というものが提供されています。インストールするためには以下のコマンドを叩いてください:

curl -L https://raw.githubusercontent.com/devkitPro/installer/master/perl/devkitARMupdate.pl -o devkitARMupdate.pl
chmod +x ./devkitARMupdate.pl
sudo ./devkitARMupdate.pl /opt/devkitPro
echo "export DEVKITPRO=/opt/devkitPro" >> ~/.bashrc
echo "export DEVKITARM=/opt/devkitPro/devkitARM" >> ~/.bashrc
source ~/.bashrc

ついでに、libctruもインストールしておきましょう。libctru は、CTR User Library という意味で、CTR とは 3DS のことです。そのユーザ空間で動かせるライブラリ、ということですね。多分。
こいつは自作アプリを作る上で必要になってくる、基本的な API を提供してくれます。ダウンロード・展開して、libctru とリネームして、/opt/devkitPro/ の下に置いてやりましょう。

参考:

データの形式

さっそくビルド... といきたい所ですが、まずは僕達が何をビルドしようとしているのかはっきりさせましょう。とりあえず、よく見るフォーマットを列挙していきます。

NCCH

これが一番重要なフォーマットです。中に色々とデータを含んだコンテナのようなもので、やたら登場します。実行可能形式のもの (CXI) とそうでないもの (CFA) に分けられます。

タイトル

ホーム画面で見るあれです。フォーマットというか、タイトルを構成する部品の集合、というニュアンスで使います。具体的な構成は、3DBrew - Data Structure を参照してください。ちなみにゲームのタイトルは SDカードに保存されますが、暗号化されているので普通は読めません。

3DSX

Homebrew Launcher 独自の実行形式です。

CIA

CTR Importable Archive の略で、タイトルをインストールするのに使われます。macOS のディスクイメージみたいな雰囲気です。

なんかふわふわした雑な説明になっちゃいましたね... ソースは全て 3DBrew です。「分かんないよばーかばーか」という方はそこをあたってください。というか僕も理解が微妙なので逆に教えてくださいばーかばーか。

さて、冒頭の「僕たちはどこへ向かっているのだろう」問題に移りますが、最初の「Homebrew Launcher からハローワールドする」という目標は、3DSXフォーマットのファイルを作れれば達成できそうです。
次の「タイトル (アプリ) からハローワールドする」という目標は、CIA を経由してインストールすることで達成できます。タイトルを直接ぶち込んで実行することはできないんですよ...

さっそく「Homebrew Launcher からハローワールドする」から片付けていきましょう:)

Homebrew Launcher からハローワールドする

今回は以下のソースをビルドします:

// main.c

#include <stdio.h>
#include <3ds.h>

int main(int argc, char** argv) {
  // LCD のフレームバッファをデフォルトの値で初期化する
  gfxInitDefault();
  // 上のスクリーンをコンソール用に初期化する
  consoleInit(GFX_TOP, NULL);

  printf("Hello 3DS World!");

  // フレームバッファを解放する
  gfxExit();
  return 0;
}

うーむ。何の変哲もないクソプログラムですね。レファレンスは こちら を参照。

ARM 向けに C のコードをクロスコンパイルするためには、arm-none-eabi-gcc を使います。

ELF から 3DSX に変換するツールには、3dsxtool というものがあります:

$ 3dsxtool --help
Usage:
    3dsxtool input.elf output.3dsx [options]

Options:
    --smdh=input.smdh : Embeds SMDH metadata into the output file.
    --romfs=dir       : Embeds RomFS into the output file.
    --appid=value     : Set 3dsx Application ID.

なので、「ほーん、こいつをビルドしてエルフちゃんを作った後に、3DSX 形式にしてやればいいんだな」って思うじゃないですかー? ちっちっちっ、まだまだ甘いねワトゥスン君。1ヶ月ぐらいサーベイを続けて分かったことですが、3DS の改造業界のコードは、とにかくビルドが通りません。情報ねぇ。Makefile しかねぇ。コードが汚ねぇ悟りを開けということですね

まぁとりあえずやってみますか:

$ arm-none-eabi-gcc -I/opt/devkitPro/libctru/include -o main.o -c main.c
$ arm-none-eabi-gcc main.o -L/opt/devkitPro/libctru/lib -lctru -o helloworld.elf
/opt/devkitPro/devkitARM/bin/../lib/gcc/arm-none-eabi/7.1.0/../../../../arm-none-eabi/bin/ld: error: /opt/devkitPro/libctru/lib/libctru.a(console.o) uses VFP register arguments, helloworld.elf does not
/opt/devkitPro/devkitARM/bin/../lib/gcc/arm-none-eabi/7.1.0/../../../../arm-none-eabi/bin/ld: failed to merge target specific data of file /opt/devkitPro/libctru/lib/libctru.a(console.o)
/opt/devkitPro/devkitARM/bin/../lib/gcc/arm-none-eabi/7.1.0/../../../../arm-none-eabi/bin/ld: error: /opt/devkitPro/libctru/lib/libctru.a(gfx.o) uses VFP register arguments, helloworld.elf does not
.
.
.

ずーっとこんなのが出て解決できませんでした。あぁハゲる。

幸いテンプレートのプロジェクトは make を叩いてビルドできたので、何をやっているのか見てみましょう。ソースは ここ です。

mkdir build && make -n
[ -d build ] || mkdir -p build
/Applications/Xcode.app/Contents/Developer/usr/bin/make --no-print-directory -C build -f /path/to/application/Makefile
echo main.c
arm-none-eabi-gcc -MMD -MP -MF /path/to/application/build/main.d -g -Wall -O2 -mword-relocations -fomit-frame-pointer -ffunction-sections -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -I/path/to/application/include -I/opt/devkitPro/libctru/include -I/path/to/application/build -DARM11 -D_3DS -c /path/to/application/source/main.c -o main.o
echo linking application.elf
arm-none-eabi-gcc -specs=3dsx.specs -g -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -Wl,-Map,application.map     main.o  -L/opt/devkitPro/libctru/lib -lctru -lm -o /path/to/application/application.elf
arm-none-eabi-gcc-nm -CSn /path/to/application/application.elf > application.lst
smdhtool --create "application" "Built with devkitARM & libctru" "Unspecified Author" /opt/devkitPro/libctru/default_icon.png /path/to/application/application.smdh
echo built ... application.smdh
3dsxtool /path/to/application/application.elf /path/to/application/application.3dsx --smdh=/path/to/application/application.smdh
echo built ... application.3dsx

なるほど全然分からない

しかし経験則上、こういう所を憶測のまま放置しておくと、後で死に至ることは分かっています。とりあえず重要そうな部分を抽出、必要ないオプションを削除して、我々のハローワールドをビルドできるコマンドを整理しました:

# コンパイル
arm-none-eabi-gcc -march=armv6k -mfloat-abi=hard -I/opt/devkitPro/libctru/include -c main.c -o main.o

# リンク
arm-none-eabi-gcc -specs=3dsx.specs -march=armv6k -mfloat-abi=hard main.o -L/opt/devkitPro/libctru/lib -lctru -o helloworld.elf

# エルフちゃんを 3DSX に変換
3dsxtool helloworld.elf helloworld.3dsx

けっこうシンプルになりましたね。最適化の処理を根こそぎ剥いだのでもとからクソだったハローワールドがさらにクソ加減を増し、クソオブザクソになっていますが、理解しやすくはなりました。残っているオプションを調べてみましょう:

  • -march=armv6k: ターゲットの ARM のアーキテクチャを arm6k に指定
  • -mfloat-abi=hard: VFP ABI を使った浮動小数点のサポートを有効にする
  • -specs=3dsx.specs: GCC の挙動をファイルに記述されたものに変更

ということで、上 2つは ARM の仕様関連のオプションでした。また、GCCコンパイルアセンブル、リンクなどのプログラムを走らせるドライバです。最後のオプションを使うことで、その挙動を変えることができるみたいです。じゃどんな風になってるの? という疑問が当然湧いてきますが、/opt/devkitPro/devkitARM/arm-none-eabi/lib/3dsx.specs を見てみると以下のようになっています:

%rename link                old_link

*link:
%(old_link) -T 3dsx.ld%s -d --emit-relocs --use-blx --gc-sections

*startfile:
3dsx_crt0%O%s crti%O%s crtbegin%O%s

わかるようなわからないような... とりあえずリンクの挙動を変えて、エントリーを main 以外にしてるっぽいのは確かです。要調査、ということでこいつは放置しておきます。

最後に、コンパイルとリンクを一度に実行するようにしたものがこちら:

arm-none-eabi-gcc -specs=3dsx.specs \
                  -march=armv6k -mfloat-abi=hard \
                  main.c \
                  -I/opt/devkitPro/libctru/include \
                  -L/opt/devkitPro/libctru/lib -lctru \
                  -o helloworld.elf

3dsxtool helloworld.elf helloworld.3dsx

ん、いい感じですね。叩くと helloworld.3dsx が出てきます。

で出てきた 3DSX を実行させたいわけですが、とりあえず 3dslink コマンドを使いましょう。
3dslink は Homebrew Launcher に WiFi 経由でプログラムを送信してくれます。まず 3DS 側で Homebrew Launcher を起動し、Yボタンを押して 3dslink netloader を起動します。以下のような画面が表示されるはずです:

f:id:deltatan:20171201061826j:plain

日本語に不自由な感じですが、気にしないのが賢明です。

さて、このアドレス宛てにホストからハローワールドを送ってやりましょう。この場合、打ちこむのは以下のコマンドになります:

3dslink --address 172.20.10.5 helloworld.3dsx

するとハローワールドが表示されます。

f:id:deltatan:20171201062728p:plain

とりあえず最初の目標は達成できました。もちろん、SDカードの /3ds/ に置いてやれば直接実行できます。

次はタイトルを作りましょう。

タイトル (アプリ) からハローワールドする

エルフからタイトルを作るには、makerom コマンドを使います。Project_CTR からダウンロード・展開し、/opt/devkitPro/devkitARM/bin/ に配置します。

先にビルドのコマンドを貼っておきます:

makerom -rsf app.rsf -desc app:2 -f cia -o helloworld.cia -elf helloworld.elf

-f, -o, -elf はいいとして、最初の 2つのオプションの説明をします。
まず -rsf app.rsf。RSF とは、NCCH の設定を指定する YAMLファイルのことです。今回は app.rsf を使いました。
次に -desc app:2 ですが、こいつはアクセスディスクリプタをテンプレートから指定するオプションです。通常は前述の .rsf ファイルを使って指定する必要がありますが、その手間を省くことができます (参考)。アクセスディスクリプタは CXI の一部っぽいですが、あまり情報がありません (参考)。これも要調査です。

出てきた helloworld.cia を SDカードに配置します。FTPD などをインストールすると送信が楽です。FBI という CIA のインストーラを使えば、CIA からタイトルをインストールすることができます。

タイトルをインストールして起動するとこんな感じになります:

ついでなのでアイコンとバナーも変えてみましょう。bannertool を使います。注意点としては、アイコン 48x48px, バナー 256x128px, ホバー時の音声 <= 3sec を満たしている必要があります。

アイコンを作って:

bannertool makesmdh -s "Hello World" -l "Hello World" -p "rounddelta" -i icon/dog.png -o helloworld.smdh

バナーを作って:

bannertool makebanner -i banner.png -a banner.wav -o banner.bin

makerom で指定します:

makerom -rsf app.rsf -desc app:2 -f cia -o helloworld.cia -elf helloworld.elf -icon helloworld.smdh -banner banner.bin

f:id:deltatan:20171201081710j:plain

できた。

いやー、長い道のりでした。しかし騙されないでください。こいつはそれっぽくなってるただのハローワールドです。全く労力が見合わない

ということで、今回は 3DS でハローワールドしてみました。ハローというか深淵を覗いた感じですが、何か役に立つ情報があれば幸いです。それでは。

3DS の改造について分かったことまとめ

※ この記事では、N3DS FW 11.3 まで使うことができた方法を前提に解説を進めます
※ 憶測で話を進める部分がありますがご容赦ください (間違いを見つけたらコメントをください)

お久しぶりです。ここ 1ヶ月程 N3DS のハックについてサーベイを続けていたので、忘れない内に記事にしておこうと思います。以下、3DS という言葉を主に N3DS という意味で使っていきますが、ハードを総称して使うこともあります。適宜読み換えてください。

さて、ゲーム機のハックと聞くとなじみがないかもしれませんが、基本的には「任意のコードの実行」です。これは iPhone の脱獄や、Android の root化でも同じことが言えます。つまりセキュリティ上の脆弱性を突いているわけで、やっていることは PC にマルウェアを感染させるのと変わらないわけです。必ず自己責任で、そしてよく調べてからハックしましょうね。

では解説に移りたいと思いますが、この記事では、「3DS のハックに使われている手法は何をやっているのか」ということをつらつらと書いています。「3DS 改造」とググると山のように情報が出てきますが、それらの多くは「どうやって導入するのか」という情報で、「何をやっているのか」という情報ではありません。なんかもやもやしませんか? 日本人が開発したゲーム機ぢゃねーかなんで英語の情報しかないんだと。そう思ったので、僕はこうして情報を記事にしています。えぇ、久々に

前提知識

ハードウェア

まずは 3DS のハードの説明からしていきます。現在、3DS のハードは N3DS, N3DS LL など複数のラインアップが展開されていますが、どのハードでも解説に支障はありません。解説に必要な部分をざっと説明すると、

  • CPU: ARM9 / ARM11 ARM9 は、DS 用ゲームの後方互換性を保つために搭載されている。
  • ブートロム ブートローダーが保存されている。物理的に分かれているのかどうか不明だが、ARM9用カーネルブートローダー (Boot9)・ARM11用カーネルブートローダー (Boot11) が存在する。
  • NAND Read Write Memory っぽいもの。ARM9用・ARM11用の 2つのカーネルが保存されている。写真データの保存などにも使われる。

という感じですね。詳しくは公式ドキュメントの 3DS オーバービューを見てください。

カーネル

3DS では、なじみ深いモノシノリックカーネルではなく、マイクロカーネルが採用されています。マイクロカーネルカーネルランドの機能をできるだけ多くのプロセスに分け、各プロセスは IPC (InterProcess Communication) を使って通信します。プロセスには、fs (File System) や Camera などがあります。

ブート

一般的な PC のブートは、

  1. 一次ブートローダー (BIOS, UEFI など) を起動。ハードウェアの初期化をする。
  2. 二次ブートローダー (GRUB など) を起動。カーネルをブートする
  3. カーネルの初期化

という流れで行われますが、3DS のブートは以下のように行われます:

  1. Boot9 と Boot11 が起動。それぞれ、NAND に保存されている ARM9用カーネルと ARM11用カーネルを、署名を検証した後に起動する。
  2. ARM11用カーネルは、必要なプロセスを起動したり、ホームメニューを表示させたりする。

つまり、ARM9用カーネルは本当に後方互換性のためだけに起動されるようなもんです。メインは ARM11用カーネルです。

ちなみに、一般的な PC で「ファームウェア」と言うと、一次ブートローダーを指すことが多いですよね? モバイル端末のカーネルも「ファームウェア」と呼ばれることが多いですが、そもそもファームウェアとはハードウェアに組み込まれて保存されているソフトウェアを指す言葉らしいです。なので、この定義で行けば、モバイル端末のカーネルを「ファームウェア」と呼ぶことは間違ってはないですが... しかしそれならモバイル端末のブートローダーだってファームウェアですし、やっぱり紛らわしいと思います。

ハック

以上の前提知識を踏まえて、ハックの話をしていこうと思います。ここで言う「ハック」とは、「Homebrew Launcher から boot9strap を導入する」ということを指しています。このハックを使うと、iPhone で言う「紐なし脱獄」ができるようになります。しかも、FW をアップデートしても CFW は永遠に消えません。つまり最強です。

導入

解説は後からするので、ここではとりあえず、導入完了までの手順を挙げさせてください。あと、これは僕が昔の FW で使った手法です。別のやり方があったり、最新の FW では動かなかったりすると思います。また、細かい部分は省くので、実際に試す場合は以下の記事を参考にしてください。英語ですが、最も信頼できるソースです。

3ds.guide
3ds.guide

  1. Soundhax を使って Homebrew Launcher を起動する
  2. udsploit を実行する
  3. safehax を実行する
  4. Luma3ds をインストールする

解説

まず、Homebrew Launcher とは、署名のないアプリやコード (Nintendo eShop で提供されていない) を実行するためのソフトです。これを実行するためには、任意のコードを実行するための、エントリーとなる脆弱性が必要になります。それが、今回は FW 11.3 まで存在していた Nintendo 3DS Sound の脆弱性で、Soundhax はそれを突いています。しかし、Homebrew Launcher はカーネルの上で動いているので、まだユーザーランドの制御しかできません。

次に、udsploit です。こいつは同じく FW 11.3 まで存在していた、カーネルランドの制御をできるようにする脆弱性を突くエクスプロイトです。詳しいことはよく分かりません。しかし、これでおそらく NAND にアクセスするための土台が手に入りました。

safehax は boot9strap というエクスプロイトを実行するためのラッパーみたいなものです。このエクスプロイトが一番重要で、ARM9用カーネルブートローダー Boot9 に存在する、sighax という脆弱性を突いています。これは、カーネルの署名をチェックするパーサーがぶっこわれていて、ある 1つの署名を付けることで NAND 上の任意のコードの実行を許してしまうような脆弱性です。また、ARM11 でコードを実行することもできるようです。工場出荷後の Boot9 でエクスプロイトに使う署名はまた変わってしまっているらしく、それをどうやって計算したかは SIGHAX AND BOOT9STRAP を見てください。前述の udsploit を使うと NAND を書き換えることができ、それを Luma3DS (CFW) を起動するような内容で書き換えれば作業は完了です。解説も終わりです。

所感

個人的には、工場出荷前のブートローダーをどうやって手に入れたのか気になるところです。それと、後方互換性のために搭載した ARM9 のブートローダーにこんだけ深刻な脆弱性があったというのは皮肉ですよね。ROM なので書き換えもできんし。

また、Homebrew Launcher を起動するのに使うエントリーの脆弱性は、システムアプリ以外のタイトル、普通のゲームにも見つかっています。この辺を卒研で見つけたい野望があるんですが、どうだろう。難しいかなぁ。

次の記事では 3DS 向けのクロスコンパイルのやり方、ライブラリなどを取り上げたいと思います。それでは。

デスノート PC侵入シーンの考察

最近デスノートを見返しているんですけど、やっぱり L が死ぬまでが一番おもしろいですね。逆に最後まで見ちゃうとジェバンニが全てをかっさらっていくので見返すときは L が死ぬところで見るのをやめてます。

さて、作中では完璧な人間として描かれている月ですが、L にセキュリティの知識があれば、割と簡単に勝てたのではないかというシーンを見つけました。それは 3話の、月が総一郎の PC に侵入して捜査資料を盗むシーンです。

ここ!
f:id:deltatan:20171030063745p:plain

月が総一郎のパソコンに侵入した後に

サーバを選んでください

というポップアップが表示され、ログイン後にキラ事件に関する全ての捜査資料がリストアップされています。これはおそらく、警察庁所有の FTPサーバに接続し、内容を見ているということでしょう。

「自分のパソコンから、何の痕跡も残さず、父さんのパソコンに侵入することさえできるよ」

と月は嘘ぶいていますが、それでも普通、サーバへのアクセスやトランザクションにはログが残るはずです。総一郎が記憶しているアクセス日時の申告と、実際のアクセス日時が違っていたら即アウトです。総一郎が捜査資料を漏洩させていた可能性も残りますが、それでも「夜神家が怪しい」ということになります。L がログさえ見ていれば FBI捜査官が死ぬこともなかったのに! *1

L は夜神家に盗聴器と監視カメラを仕掛けていましたが、僕ならフォワードプロキシをかませて通信を盗聴します。月が総一郎のパソコン・ダミーの FTPサーバに不正アクセスしていることを確認し、しかるべき証拠保全が完了した段階で勝負も終わりです。あ、でもデスノートも押さえないといけないのか。まぁこれも、月のパソコンにマルウェアでもしこんで、インカメで「僕は新世界の神になる」あたりのシーンを押さえればいいんじゃないですか。

しかしあの月のことです。FTPサーバにアクセスしたときに、実はサーバにも侵入して、アクセスログを改竄しちゃったりしてるかも... まさかねぇ。いや、いくら極秘の捜査資料をシンクライアントも使わずにアクセスさせているとはいえまさか。容易に推測できるようなパスワード使ったりしてるけどさすがの月でも... いやできるわ! むしろ余裕だわ!

どうか L には、キラ対策本部にセキュリティエンジニアを雇うことを考えてもらいたいものですな。

*1:L は FBI捜査官の死から月がキラである可能性に気付いた

備忘録 9月前半

deltatan.hatenablog.com

8月の終わりに「簡単なニュースとか備忘録的なものを毎日残していく」宣言をしたわけですが、まぁ無理だったよね。いや言い訳をさせて頂くと、9月に入ってから勉強の速度を上げたり、インターンあえて炎上案件に飛びこんだり, なかなか体力持ってかれるようなことばっかしてたんで。
ぶっちゃけセキュキャンの方がきつかったけどな!

まぁ... その... この怠惰の一番の原因はどうせ誰も見てないからいいだろ的な何かだったりするんですけど、それはどうしようもないですね。まぁ、今更ながら 9月前半を振り返ってみます (といってもあんま覚えてないんでツイッターをおもむろに開きながら)。

備忘録

OWASP Nagoya Local Chapter Meeting 1st に参加

9/2 にあった OWASP のイベントに参加してきました。いやー、想像以上におもしろかったですね。OWASP の岡田さんとか、徳丸本の徳丸さんとかの話を聞いてきましたよ。
岡田さんの話で印象に残ってるのは、問題の根本的な原因を考える、シフトレフトの話ですね。これはトヨタ的な思考だなーって思いながら聞いてました。
徳丸さんには SQLインジェクションとか CSRF とかの実演をして頂きました。やっぱ実際に使われてる攻撃を見るのは楽しかったですね。

以下、問題発言名言

「マ◯クロソフトの人間が、日本の大企業の 95% は何かしらのセキュリティ上の問題を抱えているって言ってた」
「サーバールームに設置してある監視カメラのリアルタイム映像をネットに漏らしてる会社があった」
「『よくわかる PHP の教科書』を血祭りにしようと思います
「今まで『よくわかる PHP の教科書』にある脆弱性を題材に色々講演とかやってきたんですが、最近売れてないみたいなんです。もしかして私のせい?


3DS のチートをいじる

現在 3DS のチートツールとして最も使われているのが、NTR CFW ってやつなんですけど、こいつを導入するとチートが C/C++ で書けるようになるんですよ。いやすごくね? 10年ぐらい前、GBA/DS 全盛期世代のチートツールであるプロアクションリプレイとかコードフリークでは、各ゲームのチートプラグインを 16進数で入力してたもんですが、どうやらバイナリアンは滅びゆく運命にあるらしい

ちなみに僕は懐古主義者なので、ポケモン ORAS を買って、チート使って瞬殺で殿堂入りしたりしてました。しっかし感心したのが、チート使ってるので最初からアイテム全て持ってたり、通常のプレイではありえないステートにしてたのにも関わらず、ゲームがフリーズしたりバグったりすることがほとんどなかったこと。しっかりガードかけてるんだろうなぁ。さすがゲーフリ! すごいぞゲーフリ!!

あと使ってるプラグインは、いろいろ勉強になりそうなのでだらだらとコード読んでいじってます。日本語化も進めているので、コミットしてくれる方はこちらまで:
github.com



さすがに 5体のゲンシカイオーガは描画処理が重かった。


VM クラッシュ問題

Bluetoothバイスに接続した途端 VM がクラッシュする問題を発見したんですが、同じ問題が 2ヶ月前に報告されていて、次のリリースで修正されるみたいです (参考: https://www.virtualbox.org/ticket/16969)。


ネタ

君の名は。いいよね