目次
OCI準拠のコンテナランタイムは、Configuration File(config.json)というコンテナ環境の設定ファイルに基づいて起動する動きになります。
config.jsonには以下のようなパラメータが含まれています。
そのほかにも様々なパラメータがあります。詳細はOCI Runtime Specificationを参照してみてください。
config.jsonはコンテナの設計図であり、これを差し替えることができれば起動するコンテナを任意の環境で実行させることが可能になります。
ここでは、RaindにおけるConfiuration Fileに対するセキュリティ対策について紹介します。
TOCTOU(Time-of-Check, Time-of-Use)とは、あるパラメータに対してチェックを行ったあと、そのパラメータを使うまでの間にパラメータを差し替えることで、チェック機構をバイパスすることで成功する攻撃手法です。
RaindにおいてConfiguration Fileの読み込み/利用する箇所は以下になります。
図に表すと以下です。
sequenceDiagram
autonumber
participant proc_create@{ "type": "control" }
participant proc_init@{ "type": "control" }
participant config.json@{ "type": "database" }
proc_create->>config.json: load config
config.json-->>proc_create:
proc_create->>proc_init: exec
proc_init->>config.json: load config
config.json-->>proc_init:
sequenceDiagram
autonumber
participant proc_create@{ "type": "control" }
participant proc_shim@{ "type": "control" }
participant proc_init@{ "type": "control" }
participant config.json@{ "type": "database" }
proc_create->>config.json: load config
config.json-->>proc_create:
proc_create->>proc_shim: exec
proc_shim->>config.json: load config
config.json-->>proc_shim:
proc_shim->>proc_init: exec
proc_init->>config.json: load config
config.json-->>proc_init:
各プロセスにおいてConfiguration Fileに基づいた処理が必要であり、すべてを各プロセスの引数で渡すことは現実的ではないため、それぞれのプロセスの開始直後にConfiguration Fileを読み込む設計になっています。
このような起動フローの場合、
にConfiguration Fileを差し替えれば、本来意図していた設定から逸脱したコンテナを起動することができます。
特にinitプロセスはコンテナとしてのエントリポイントや環境変数、ファイルシステムのマウント等の重要な処理が走るため、ここで差し替えが発生してしまった場合かなり危険です。
sequenceDiagram
autonumber
participant proc_create@{ "type": "control" }
participant proc_init@{ "type": "control" }
participant config.json@{ "type": "database" }
participant MaliciousUser@{ "type": "actor" }
proc_create->>config.json: load config
config.json-->>proc_create:
proc_create->>proc_init: exec
rect rgb(66, 12, 12)
note right of proc_init: ATTACK
MaliciousUser->>config.json: inject malicious parameter
proc_init->>config.json: load config
config.json-->>proc_init:
proc_init->>proc_init: exec Entrypoint
note over proc_init: Malicious Entrypoint
end
対策として、いずれのモデルにおいても共通しているのは”createプロセスで読み込んだConfiguration Fileで起動すること”です。※Configuration Fileの内容自体の検査は別で対策する前提。
RaindではConfiguration Fileを読み込む際に、以下のような処理を行っています。
xxとyyの間に差し替えられたら?という発想は出てきますが、ゼノンのパラドックス(アキレスと亀)みたく、チェックするタイミングと使うタイミングを完全に0にすることはできません。
ポイントは、いかにチェックと使うまでの間隔を短くするか、チェック機構を増やし攻撃が成功しにくくなるか、です。
この仕組みによって、攻撃者は
この2つを短時間で実行させる必要があるため、攻撃成功率は各段に下がります。
まずはPoCとして上記の検証を実装しない状態で、initプロセスのConfiguration File読み込み前にsleepを組み込み、手動でConfiguration Fileを書き換えます。
まずはコンテナを作成します。
$ raind container create -t ubuntu
container: 01kfcmayge4v created
ここでinitプロセスはConfiguration Fileを読み込まず待機しているため、手動でConfiguration Fileを書き換えます。 今回はわかりやすくコンテナ起動時のディレクトリ位置(cwd)を書き換えます。
{
"ociVersion": "1.3.0",
"root": {
"path": "/etc/raind/container/01kfcmayge4v/merged"
},
"mounts": [],
"process": {
// "cwd": "/", <- original
"cwd": "/home" // <- inject malicious parameter
書き換え後、コンテナを起動してアタッチします。
$ raind container start 01kfcmayge4v
container: 01kfcmayge4v started
$ raind container attach 01kfcmayge4v
Attached. Detach with Ctrl-P Ctrl-Q
root@01kfcmayge4v:/home# pwd
/home
コンテナ作成時点(createプロセス)で読み込んだConfiguration Fileは”/”がWDとして指定されていましたが、コンテナ開始時点(initプロセス)で読み込んだConfiguration Fileは”/home”に書き換わっており、起動したコンテナのWDが変わってしまっています。
Configuration Fileの読み込みを対策に記載した処理にして再度試してみます。 起動と書き換えまでは同じです。
$ raind container create -t ubuntu
container: 01kfcmhkafsw created
// configuration file書き換え
{
"ociVersion": "1.3.0",
"root": {
"path": "/etc/raind/container/01kfcmhkafsw/merged"
},
"mounts": [],
"process": {
// "cwd": "/", <- original
"cwd": "/home" // <- inject malicious parameter
ここで起動します。startコマンドは開始シグナルの送信のみのため、起動後にステータスを確認します。
$ raind container start 01kfcmhkafsw
container: 01kfcmhkafsw started
$ raind container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
01kfcmhkafsw ubuntu:latest "/bin/bash" 1 minutes ago stopped
コンテナが停止しているようです。ここで、ログを確認してみます。
$ cat /etc/raind/container/01kfcmhkafsw/logs/console.log
2026/01/20 11:43:37 config.json hash validation failed: expect=xxx, got=yyy
2026/01/20 11:43:37 container startup failed
Configuration FileのHash突合に失敗し、コンテナの起動ができていないことが確認できます。