TT Lab
はじめる
学ぶ 学習パス コース

閉域網の現場 — 防衛ドメイン

搬入バンドルを作り署名検証が壊れる場所を見つける

TT Labで続きを見る

目標

エアギャップ環境に入れる持ち込みバンドルを最初から作って署名し、受け取る側になって検証し、検証がどこで壊れるかを、2種類の改ざんで直接確認します。

なぜ重要なのか

このPodにはgpgがなく、インストールすることもできません。実際のエアギャップ環境も、たいていそうです。許可リストにないソフトウェアは、それ自体が持ち込み審査だからです。そのため、どこにでもあるopensslで署名と検証を行います。そして、完全性は1つの層ではなく、2つの層です。ファイルのハッシュは「一覧が言うそのファイルか」を、署名は「その一覧を知っている人が作ったか」を守ります。1つの層だけを見ると、必ず片方を通してしまい、その事実は、2つの場合を自分で作ってみる前には、実感できません。

ステップ

  1. python3で/root/bundle/payload/の下に6つのファイルを作ります。2つはバイナリです。
  2. /root/bundle/stage/MANIFEST.sha256に、ファイルごとのSHA-256を相対パスで取ります。
  3. /root/bundle/keys/にRSA 2048の鍵ペアを作り、秘密鍵の権限を600に、公開鍵のフィンガープリントをrelease.pub.sha256に残します。
  4. openssl dgst -sha256 -signで/root/bundle/stage/MANIFEST.sigを作ります。
  5. /root/bundle/out/intake-2609-01.tar.gzとして束ね、同じ名前の.sha256を取ります。鍵ファイルは入れません。
  6. /root/bundle/recv/に展開して、バンドルのハッシュ → 署名 → ファイルのハッシュの順に検証し、結果をreceipt.txtに書きます。
  7. /root/bundle/tamper-a/と/root/bundle/tamper-b/に2種類の改ざんを入れ、結果を/root/bundle/tamper.txtに書きます。Aはpayload/deps/libpq.so.5.binの1バイトだけを、Bはそれに加えて、マニフェストのその行まで書き換えます。
  8. /root/bundle/intake.mdに、7つの節からなる持ち込み承認申請書を書きます。

参考

持ち込むツリーを作る

python3で/root/bundle/payload/の下に6つのファイルを作ります。2つはバイナリです。

python3で6つのファイルを作ります。そのうち2つはバイナリなので、目では確認できず、フィンガープリントでだけ確認します。生成スクリプトは直さず、そのまま使ってください。

ファイルごとのハッシュマニフェストを取る

/root/bundle/stage/MANIFEST.sha256に、ファイルごとのSHA-256を相対パスで取ります。

payloadディレクトリの中で、相対パスで取ります。findの-printf '%P\n'が、先頭の./を取り除いてくれます。受け取る側は別のディレクトリに展開するので、絶対パスはその場で役に立ちません。

署名用の鍵ペアを作ってフィンガープリントを残す

/root/bundle/keys/にRSA 2048の鍵ペアを作り、秘密鍵の権限を600に、公開鍵のフィンガープリントをrelease.pub.sha256に残します。

openssl genrsaで2048ビットの秘密鍵を作り、権限を600にします。公開鍵は-puboutで取り出し、フィンガープリントは、DERに変換したあと、sha256sumを取ります。

マニフェストに署名する

openssl dgst -sha256 -signで/root/bundle/stage/MANIFEST.sigを作ります。

署名の対象は、ペイロード全体ではなく、マニフェスト1枚です。openssl dgst -sha256 -signには、-outを必ず付けてください。画面出力をリダイレクトすると、バイナリが壊れます。

バンドルに束ねる(鍵は入れない)

/root/bundle/out/intake-2609-01.tar.gzとして束ね、同じ名前の.sha256を取ります。鍵ファイルは入れません。

ペイロードとマニフェストと署名を1つに束ねます。公開鍵は入れません。バンドルと同じ経路で来ると、その経路を手にした人が、4つすべてをすり替えられます。束ねたあと、tar -tzfで、何が入ったかを目で確認してください。

受け取る側の手順を順番どおりに踏む

/root/bundle/recv/に展開して、バンドルのハッシュ → 署名 → ファイルのハッシュの順に検証し、結果をreceipt.txtに書きます。

順序が核心です。バンドル全体のハッシュ → 署名 → ファイルごとのハッシュ。ファイルのハッシュを先に見ると、まだ真正性が確認されていない一覧を基準に突き合わせることになります。

検証がどこで壊れるかを2つの場合で確認する

/root/bundle/tamper-a/と/root/bundle/tamper-b/に2種類の改ざんを入れ、結果を/root/bundle/tamper.txtに書きます。Aはpayload/deps/libpq.so.5.binの1バイトだけを、Bはそれに加えて、マニフェストのその行まで書き換えます。

複製を2つ作って、Aにはバイナリの1バイトだけを変え、Bには同じ改ざんに加えて、マニフェストのその行まで新しいハッシュに書き換えます。2つとも、署名の検証とファイルのハッシュの突き合わせをかけてみてください。

持ち込み承認申請書を書く

/root/bundle/intake.mdに、7つの節からなる持ち込み承認申請書を書きます。

7つの節が必要です。審査者が私たちの画面なしで同じ検証をやり直せなければならないので、「通過しました」ではなく、値とコマンドを書きます。